简体   繁体   中英

Why does Typescript with strictNullChecks enabled ignores null checks on React's state?

In the following example:

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>;
    }
}

An error arises under <Child text={this.state.text} /> :

Type 'null' is not assignable to type 'string'.ts(2322)

打字稿错误,即使检查为空

This does not make sense since there's an explicit null check prior to its render.

Why when extracting text from state, the error goes away?

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

A working example with the error enabled, replace the code in order to see it fixed:

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

if you initialize state as class property, you need declare its type definition. otherwise typescript assumes you override its type that inherits from React.Component<{}, AppState> , and its type becomes { text: null }

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

or just initialize state in constructor

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

        this.state = {
            text: null
        }
    }
}

as for extracting

// 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
}

see more at https://www.typescriptlang.org/docs/handbook/basic-types.html#never

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM