在Typescript React类组件中扩展RouteComponentProps的道具的扩展接口和交点类型之间的区别?

时间:2020-10-02 18:00:03

标签: reactjs typescript react-router

Typescript中扩展接口和交集类型有什么区别?我不明白结果类型有何不同,特别是对于扩展非重叠属性的简单情况。

在以下键入React类组件的props的示例中,为什么扩展接口无法正确扩展RouteComponentProps(也是一个接口),但是交集类型会导致正确的键入/属性?

import React, {PureComponent} from 'react';
import {RouteComponentProps, withRouter} from 'react-router-dom';

// Interface fails to extend the properties
interface Props extends RouteComponentProps {}

// But if we used an intersection type, that works
// type Props = {} & RouteComponentProps

class MyComponent extends PureComponent<Props> {
    constructor(props: Props) {
        super(props);
    }

    render() {
        console.log('All props', this.props); // Prints all props including routing-related

        // Error here: Property 'history' does not exist on type 'Props'.  TS2339
        console.log('History - ', this.props.history);
        
        return <p>Hello World!</p>;
    }
}

export default withRouter(MyComponent);

IDE(VSCode)显然可以通过intellisense(使用点运算符显示自动完成选项)来获取正确的类型/属性。但是,Typescript编译器给出了错误

Property 'history' does not exist on type 'Props'.  TS2339

我不明白为什么(因为我认为结果类型应该扩展相同的属性),但是如果将Props定义为与RouteComponentProps的交集类型,那么它将起作用。

type Props = {} & RouteComponentProps;

这是为什么?发生了什么,接口扩展没有按预期降低属性?

在这个更简单的接口扩展示例中,一切正常,没有TS编译器错误。

interface A {
    x: string;
}

interface B extends A {
    y: string;
}

function doSomething(something: B) {
    console.log(something.x);
}

doSomething({x: 'Whatever', y: 'Whatever'});

所以我对接口扩展与类型交集的区别感到困惑。

重申主要问题:
扩展接口和Typescript中的交集类型有什么区别?

在TS Playground上尝试示例

在3.9.7(convenience link with code and on 3.9.7)的TS Playground中尝试代码示例,导入的.d.ts定义实际上很不错,但是随后我得到了一些非显而易见的控制台错误以及实际上不会显示的侧边栏错误。请看下面的屏幕快照,它演示了两个: TS Playground code example with console and sidebar errors

0 个答案:

没有答案