我试图让我粘贴在下面的代码执行,但Typescript编译器似乎不相信我已经正确地确保了一个接口可以根据我所做的判断转换为另一个接口.我需要做些什么才能让它满意这个代码?


interface Person {
  name: string,
  address?: string
}

interface PersonWithAddress extends Person {
  address: string
}

function tryLoggingAddresses(people: Array<Person>) {
  people.forEach(person => {
    if (person.address) {
      logAddress(person)
    }
  })
}

function logAddress(personWithAddress: PersonWithAddress) {
  console.log(personWithAddress.address)
}

Typescript错误:

error TS2345: Argument of type 'Person' is not assignable to parameter of type 'PersonWithAddress'.
      Types of property 'address' are incompatible.
        Type 'string | undefined' is not assignable to type 'string'.
          Type 'undefined' is not assignable to type 'string'.

    63       logAddress(person)

我知道我可以通过将行更改为logAddress(person as PersonWithAddress)来强制转换,但这实际上禁用了所有不理想的类型判断.有没有办法做到这一点?

推荐答案

可以使用type guard代替现有的条件表达式.这将有助于告知编译器,数据 struct 符合control flow analysis期间所需的标准.

TypeScript Playground

function personHasAddress (person: Person): person is PersonWithAddress {
  return typeof person.address === 'string';
}

function logAddresses (people: Person[]) {
  for (const person of people) {
    if (personHasAddress(person)) logAddress(person);
  }
}

Typescript相关问答推荐

使用类和子类以及迭代类属约束对类属递数据 struct 建模

为什么当类类型与方法参数类型不兼容时,该函数可以接受类类型

如何在不使用变量的情况下静态判断运算式的类型?

相同端点具有不同响应时的RTKQuery类型定义

如果我有对象的Typescript类型,如何使用其值的类型?

在Typescribe中,extends工作,但当指定派生给super时出错""

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

TypeScrip:基于参数的条件返回类型

未在DIST中正确编译TypeScrip src模块导入

在函数中打字推断记录的关键字

用于验证字符串变量的接口成员

如何在已知基类的任何子类上使用`extends`?

迭代通过具有泛型值的映射类型记录

复选框Angular 在Ngfor中的其他块中重复

为什么上下文类型在`fn|curred(Fn)`的联合中不起作用?

TypeScrip:从嵌套的对象值创建新类型

如何在Vue动态类的上下文中解释错误TS2345?

JSX.Element';不可分配给类型';ReactNode';React功能HOC

为什么过滤器不改变可能的类型?

使用本机 Promise 覆盖 WinJS Promise 作为 Chrome 扩展内容脚本?