Почему только функции со встроенной типизацией обнаруживают дополнительные поля? - PullRequest
1 голос
/ 05 марта 2020

У меня сложилось впечатление, что эти функции, хотя и написаны по-разному, имеют одинаковую точную сигнатуру типа; ie

type Test = {
  a: number
}
type Fu = (a: number) => Test

var foo1: (a: number) => Test = a => ({ a }) // aka var foo1: Fu = a => ({ a })
var foo2 = (a: number): Test => ({ a })  

Недавно я обнаружил, что один из них позволяет передавать дополнительное поле в

var foo1: (a: number) => Test = a => ({ a, b:1}) // NO error!
var foo2 = (a: number): Test => ({ a, b:2 }) // 'b' does not exist 

Почему это так? это ошибка или ограничение TS?

Иногда я не могу набрать встроенную функцию (ie обобщение, овериды, обратные вызовы). Есть ли другой способ определить их, чтобы они всегда действовали как foo2?

детская площадка

1 Ответ

1 голос
/ 05 марта 2020

Typescript выполняет избыточную проверку свойств для литералов объекта, но только когда литерал объекта используется в контексте, где указан его тип. Когда литерал объекта появляется в контексте, где выводится его тип, тогда не существует указанного типа для проверки.

В выражении (a: number): Test => ({a, b: 2}) возвращаемая аннотация типа : Test указывает, какой тип объекта должно быть литералом, поэтому Typescript выполняет избыточную проверку свойств.

В присваивании var foo1: (a: number) => Test = a => ({a, b: 1}) правая часть - это функция, тип которой выводится как (a: number) => {a: number, b: number}, что является совершенно разумным типом функции. В самой функции нет аннотации типа, поэтому литерал объекта используется для определения типа возвращаемого значения функции, а не типа возврата функции, используемого для проверки литерала объекта. Тогда нет ошибки, потому что тип функции можно назначить типу foo1 (поскольку типы функций ковариантны в своих типах возвращаемых данных).

Я не уверен, каким будет подходящий обходной путь, но это в любом случае, это объяснение, почему это происходит.

...