Почему Typescript допускает подтипы? - PullRequest
1 голос
/ 15 марта 2019

Согласно документации, "Совместимость типов в 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);

Есть ли другие примеры, которые я мог бы пропустить?

1 Ответ

2 голосов
/ 15 марта 2019

Причина, по которой Typescript использует структурную типизацию, заключается в том, что в JS используется тип Duck.

Таким образом, вы можете сделать то, что написали выше в JS, в идеале вы можете сделать это в TS просто более безопасным способом. Javascript не заботится о заявленных типах объектов, в JS такого понятия нет, он заботится только о свойствах, которые объекты имеют во время выполнения. Таким образом, любой объект может быть передан в вашу функцию getName, и, пока существует свойство name, функция, вероятно, будет функционировать правильно.

Более того, поскольку у JS есть литералы объектов, которые не принадлежат конкретному классу, было бы трудно явно указывать отношения наследования везде. Явная привязка типов сделала бы TS менее привлекательным для разработчиков JS. В системе структурных типов типы работают в основном по-нашему, и вы получаете от этого большую выгоду, не будучи очень явными.

Существуют способы, позволяющие обойти структурную типизацию и имитировать нормативный тип в машинописи либо с помощью закрытых свойств ( ex ), либо с использованием фирменных типов ( ex )

...