1

根据文档,“TypeScript 中的类型兼容性基于结构子类型”。所以这是可能的:

type Person: {
  name: string;
}

const developer = {
  name: 'Joe',
  language: 'Typescript',
}

// this is ok because Person is a subtype of typeof developer
const otherDeveloper: Person = developer; // who writes code like that?!

这有很多后果,其中之一是在使用 Object.keys 时会丢失类型信息:

// "keys" type is array of strings not `name` literal as this would be of course wrong because in runtime "keys" is ['name', 'language']
const keys = Object.keys(otherDeveloper); 

因此,我试图按照他们的承诺在 TS 文档中找到这种子类型的原因,但我找不到

仔细考虑了 TypeScript 允许不合理行为的地方,在整个文档中,我们将解释这些情况发生的地方以及它们背后的激励场景。

这可能对我有帮助的唯一地方是一个需要更窄类型对象的函数,例如:

function getName(person: Person) {
  return person.name;
}

getName(developer); // works fine because of subtyping

如果您在这种情况下必须使用强制转换,我个人认为这不是什么大问题:

getName(developer as Person);

还有其他我可能遗漏的例子吗?

4

1 回答 1

3

Typescript 使用结构类型的原因是 JS 是鸭子类型。

所以你可以在 JS 中做你上面写的,理想情况下你可以在 TS 中以更安全的方式来做。Javascript不关心对象声明的类型,JS中没有这个概念,它只关心对象在运行时的属性。因此,任何对象都可以传递到您的getName函数中,只要 name 属性存在,该函数就可以正常运行。

此外,由于 JS 具有不属于特定类的对象字面量,因此很难在任何地方明确指定继承关系。明确类型关系会使 TS 对 JS 开发人员的吸引力降低。在结构类型系统下,类型主要适用于我们,您可以从中获得很多好处,而不必非常明确。

有一些方法可以通过使用私有属性 ( ex ) 或使用品牌类型 ( ex )来绕过结构类型并在 typescript 中模仿规范类型

于 2019-03-15T11:40:45.667 回答