代码之家  ›  专栏  ›  技术社区  ›  mpen

当我显式地将对象包装在“if”中时,为什么TS会抱怨对象可能为null?

  •  1
  • mpen  · 技术社区  · 6 年前

    这是我的密码:

    import React from 'react';
    
    export default class ErrorBoundary extends React.Component {
    
        state = {error: null, errorInfo: null};
    
        componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
            this.setState({
                error: error,
                errorInfo: errorInfo
            })
        }
    
        render() {
            if (this.state.errorInfo) {
                return (
                    <div>
                        <h2>Something went wrong.</h2>
                        <pre>
                            <code>
                                {String(this.state.error)}
                                {this.state.errorInfo.componentStack} // <-- error is here
                            </code>
                        </pre>
                    </div>
                );
            }
    
            return this.props.children;
        }
    }
    

    消息是:

    [at loader]./src/components/ErrorBoundary中出错。tsx:22:30 TS2531:对象可能为“null”。

    enter image description here

    if 如果 this.state.errorInfo null ,所以我不确定是什么问题。

    即使我这样写:

     {this.state.errorInfo !== null ? this.state.errorInfo.componentStack : 'hello'}
    

     {this.state && this.state.errorInfo ? this.state.errorInfo.componentStack : 'hello'}
    

    我也有同样的错误。


    t配置好测量:

    {
        "compilerOptions": {
            "strict": true,
            "importHelpers": false,
            "inlineSources": true,
            "noEmitOnError": true,
            "pretty": true,
            "module": "ES6",
            "noImplicitAny": true,
            "suppressImplicitAnyIndexErrors": false,
            "removeComments": true,
            "preserveConstEnums": false,
            "sourceMap": true,
            "lib": ["es2018","dom"],
            "skipLibCheck": true,
            "outDir": "dist",
            "target": "es2018",
            "declaration": true,
            "resolveJsonModule": false,
            "esModuleInterop": false,
            "jsx": "react",
            "moduleResolution": "node",
            "allowSyntheticDefaultImports": true
        },
        "files": [
            "src/index.tsx"
        ],
        "include": [
            "src/types/**/*.d.ts"
        ],
        "exclude": [
            "node_modules"
        ]
    }
    
    2 回复  |  直到 6 年前
        1
  •  8
  •   jbialobr    6 年前

    看来

    state = {error: null, errorInfo: null};
    

    state 的类型。errorInfo的推断类型始终为 null 您可以通过显式提供类型来更正它:

    state: { error: Error | null, errorInfo: React.ErrorInfo | null } =
    { error: null, errorInfo: null };
    

    这个问题在这里报告和讨论 https://github.com/Microsoft/TypeScript/issues/10570

        2
  •  0
  •   maxpaj    4 年前

    当我在应用程序中使用状态变量时,我仍然看到这个问题 map .

    render() {
        if (!this.state.foo) { return <Loading /> }
    
        [1,2,3].map(n => {
            this.state.foo.property; // Object possibly null
        }
    
        ...
    }
    

    我通过以下方法解决了这个问题:

    render() {
        if (!this.state.foo) { return <Loading /> }
    
        const foo = this.state.foo;
    
        [1,2,3].map(n => {
            foo.property; // Cool!
        }
        
        ...
    }
    
        3
  •  -2
  •   Amir    6 年前

    状态更新是异步的,在呈现之前不应该依赖它来更新。

    你应该多看看 React component lifecycle

    如果你不想使用redux(这也是有争议的-redux是复杂的,你应该只在你需要的时候使用它,但是状态操作并不容易,所以你无论如何都应该使用它)

    说到这里。。。只需在读取之前执行一个条件检查(同样是异步的)

    constructor(props) {
      super(props);
      this.state = {init: here};
    }
    

    构造函数是唯一应该直接分配this.state的地方。在所有其他方法中,需要改用此.setState()。