为什么启用了strictNullChecks的Typescript会忽略对React状态的空检查?

时间:2019-05-16 12:45:45

标签: javascript reactjs typescript

在以下示例中:

interface AppState {
    text: string | null;
}

interface ChildProps {
    text: string;
}

class App extends React.Component<{}, AppState> {
    state = {
        text: null
    };
    componentDidMount() {
        setTimeout(() => {
            this.setState({ text: "rendered!" });
        }, 5000);
    }
    render() {
        return this.state.text !== null ? (
            <Child text={this.state.text} />
        ) : (
            "loading..."
        );
    }
}

class Child extends React.Component<ChildProps> {
    render() {
        const { text } = this.props;
        return <div>{text}</div>;
    }
}

<Child text={this.state.text} />下出现错误:

  

类型'null'不能分配给类型'string'.ts(2322)

typescript error even with a null check

这是没有意义的,因为在渲染之前有一个明确的null检查。

为什么从状态中提取text时错误消失了?

render() {
        const { text } = this.state;
        return text !== null ? (
            <Child text={text} />
        ) : (
            "loading..."
        );
    }

一个启用了错误的工作示例,请替换代码以使其得到修复:

https://codesandbox.io/s/react-typescript-playground-g15mw

1 个答案:

答案 0 :(得分:1)

如果将状态初始化为类属性,则需要声明其类型定义。否则,打字稿会假定您覆盖从React.Component<{}, AppState>继承的其类型,并且其类型变为{ text: null }

class App extends React.Component<{}, AppState> {
    state: AppsState = {
        text: null
    };
}

或者只是在构造函数中初始化状态

class App extends React.Component<{}, AppState> {
    constructor(props: {}) {
        super(props)

        this.state = {
            text: null
        }
    }
}

关于提取

// typeof this.state === { test: null }
const { text } = this.state;

if (this.state.text !== null) {
    // typeof this.state.text is still null
}

if (text !== null) {
    // typeof text is never here
    // since never is subtype of all types
    // text can be assigned to any variable
}

https://www.typescriptlang.org/docs/handbook/basic-types.html#never上查看更多信息