合并打字稿声明以扩展或覆盖模块类型或接口属性

时间:2019-02-28 11:28:03

标签: reactjs typescript react-router

我正在使用@types/react-router-dom4.3.1中的类型,该类型从@types/react-router@types/history中导入类型。

在我的应用程序中,我始终在位置状态下具有两个属性,并且希望它们自动从RouteComponentProps接口中拉出,而不必每次都将自定义LocationState类型的变量传递给该接口

RouteComponentProps接口的定义在react-router中,其内容如下:

import * as H from 'history';

export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {}, C extends StaticContext = StaticContext, S = H.LocationState> {
  history: H.History;
  location: H.Location<S>;
  match: match<Params>;
  staticContext?: C;
}

history中引用的接口/类型的定义为:

export interface Location<S = LocationState> {
    pathname: Pathname;
    search: Search;
    state: S;
    hash: Hash;
    key?: LocationKey;
}

export type LocationState = History.LocationState;

export namespace History {
    export type LocationState = any;
}

我想要的是扩展Location接口的状态属性类型定义以包括一个自定义接口(即,包括始终可用的属性)。类似于state: S & { A: string; B: string; }

我已经尝试在RouteComponentProps的模块声明中重新声明react-router接口,但是我尝试的所有结果都会在All declarations of 'RouteComponentProps' must have identical type parameters.ts(2428)Subsequent property declarations must have the same type. Property 'location' must be of type 'Location<S>', but here has type 'any'.ts(2717)中产生。

我还尝试过在历史模块声明中重新声明Location接口,其结果相同。之后,我尝试在LocationState命名空间的内部和外部重新声明History类型,但这总是导致Duplicate identifier 'LocationState'.ts(2300)

除了为具有不同名称的RouteComponentProps编写自定义界面以外,我还能做些什么来获得所需的行为吗?我希望能够在项目中导入该接口,使用该接口扩展组件的道具,并具有可从A访问的属性的Bprops.location.state类型,但是还能够处理任何其他属性,例如any无需每次都传递类型变量定义

1 个答案:

答案 0 :(得分:0)

这可能不是您正在寻找的解决方案,但我通常有一个自定义位置界面(可能从您应用上的共享 .ts 文件导出),然后使用 useLocation 挂钩那个界面。

import React, { ReactElement } from "react";
import { useLocation } from "react-router-dom";

interface CustomLocationState {
    A: string;
    B: string;
}

export default ():ReactElement => {
    const { state: {A, B} } = useLocation<CustomLocationState>();

    return <div>{A} - {B}</div>
}