简体   繁体   English

为什么 typescript 类型保护不适用于 object 的内部属性

[英]Why typescript typeguard doesn't work for an internal property of an object

Using typescript, when a function returns an object that has properties that might be null.使用 typescript,当 function 返回一个 object 时,它的属性可能是 Z37A6259CC0C1DAE299A78BDFF864。 Why does using a typeguard on these inner properties not allow typescript to infer that the inner prop must not be null after the guard?为什么在这些内部属性上使用 typeguard 不允许 typescript 推断出内部 prop 在保护之后不能是 null ?

Here's a minimum example of this.这是一个最小的例子。 Try it 试试看

interface DatabaseResponse {
  settings: string | null
}
interface MainResponse {
  settings: string
}

const retrieveFromDatabase = (): DatabaseResponse => {
  return {
    settings: 'always a string but lets pretend it could be null sometimes'
  }
}

const main = (): MainResponse | Error => {
  const data = retrieveFromDatabase()

  if (data.settings === null) {
    throw new Error()
  }

  return data

}

The error for the return of the main function is主function返回的错误是

Type 'DatabaseResponse' is not assignable to type 'MainResponse | Error'.
  Type 'DatabaseResponse' is not assignable to type 'MainResponse'.
    Types of property 'settings' are incompatible.
      Type 'string | null' is not assignable to type 'string'.
        Type 'null' is not assignable to type 'string'.

That's not really a type guard.那不是真正的类型后卫。 You can do this instead:你可以这样做:

interface DatabaseResponse {
    settings: string | null
}
interface MainResponse {
    settings: string
}

const retrieveFromDatabase = (): DatabaseResponse => {
    return {
        settings: 'always a string but lets pretend it could be null sometimes'
    } as DatabaseResponse
}

const main = (): MainResponse | Error => {
    const data = retrieveFromDatabase()

    if (!isMainResponse(data)) {
        throw new Error()
    }

    return data
}

const isMainResponse = (data: DatabaseResponse | MainResponse): data is MainResponse {
  return !!data.settings;
}

Or similarly, create a new nonNullable type with the same typeguard或者类似地,使用相同的类型保护创建一个新的 nonNullable 类型

type NonNullableDB = { [K in keyof DatabaseResponse]: NonNullable<DatabaseResponse[K]> }

const isMainResponse = (data: DatabaseResponse | MainResponse): data is NonNullableDB => {
    return !!data.settings;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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