为什么Typescript允许子类型化?

问题描述 投票:1回答: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);

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

typescript subtyping structural-typing
1个回答
2
投票

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

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

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

有很多方法可以通过使用私有属性(ex)或使用品牌类型(ex)来解决结构类型并模仿打字稿中的规范类型

© www.soinside.com 2019 - 2024. All rights reserved.