在三元运算符中进行类型检查后,打字稿无法推断出正确的类型

Typescript not inferring correct type after type check inside a ternary operator

我有这个组件需要一个 error 属性,它可能是 nullstringstring[]


interface ErrorComponent {
  error: null | string | string[]      // props.error UNION TYPES
}

const ErrorComponent: React.FC<ErrorComponent> = (props) => {

  const errorItems = props.error ?               // CHECK IF props.error EXISTS (string | string[])
    Array.isArray(props.error) ?                 // CEHCK IF props.error IS AN ARRAY
      props.error.map((item,index) =>            // CASE string[]
        <Error_DIV 
          key={index} 
          marginBottom={index === props.error.length -1 ? "0px" : "8px"}   // GETTING WARNING FOR POSSIBLE null HERE
        >
          {item}
        </Error_DIV>
      )
    : <Error_DIV>{props.error}</Error_DIV>       // CASE string
  : null;                                        // CASE null

  // return SOMETHING
};

Typescript 抱怨 props.error 可能是 null。但那时,我已经进行了检查 Array.isArray(props.error)。所以,props.error 不可能是 null.

我该如何解决这个问题?

看来这个TSLint规则对JSX的支持不是很好:

props.error.map((item,index) => 
    <Error_DIV // Here TSLINT context seems to be reset

不过,建议使用猫王运算符“?”。但在您的情况下,由于“-1”操作,这是不可能的。所以你必须再次测试props.error:

你的情况:

marginBottom={props.error && index === props.error.length -1 ? "0px" : "8px"} 

我在可能具有不同类型的数组上使用 map() 时遇到了类似的错误。您检查了 null 并检查了一个数组,因此当这些检查通过时,您可以确定您的错误道具是一个字符串数组,您可以这样做:

(props.error as string[]).map((item,index)

或者您可以在 shorthand if 语句

中的 props.error 上直接使用 string[]
marginBottom={index === (props.error as string[]).length -1 ? "0px" : "8px"}

添加额外的空检查:

marginBottom={props.error && index === props.error.length -1 ? "0px" : "8px"}

使用 ! operator 将此 属性 定义为非空:

marginBottom={index === props.error!.length -1 ? "0px" : "8px"}