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:
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.