#javascript #typescript
Вопрос:
Имея такой простой код:
interface ServerData {
foo: string
bar: number
}
const oo = {
foo: "abc",
bar: 887
}
function foo<ServerData>(x: ServerData): number { return x.foo }
Я получаю ошибку в
последней строке:
Property 'foo' does not exist on type 'ServerData'
Это странно, так ServerData
как интерфейс уже определен выше. Что происходит?
Ответ №1:
Это связано с тем, что универсальный тип ServerData
, определенный в функции, может не обладать свойством foo
(универсальный и интерфейс-это не одно и то же, вы должны сообщить об этом компилятору).
Нигде в коде вы не говорите компилятору, что универсальный код обладает этим свойством. В вашем случае вы могли бы полностью избавиться от общего типа, как это (также вам пришлось бы преобразовать foo
в число, так как функция возвращает число):
function foo(x: ServerData): number { return Number(x.foo) }
или вы могли бы сообщить компилятору, что универсальный тип в функции реализует ServerData
интерфейс следующим образом:
function foo<T extends ServerData>(x: T): number { return Number(x.foo) }
Основная проблема здесь заключается в том, что вы не сообщаете компилятору, что на самом деле представляет собой этот тип, поэтому он не знает, что параметр обладает этим свойством. Если вы хотите передать универсальный код и сообщить компилятору, что свойство foo
существует, вы также можете сделать это:
function foo<T extends {foo: string}>(x: T): number { return Number(x.foo) }
Ответ №2:
Дополнение к ответу @WilsonPena.
В вашем объявлении foo
функции ServerData
указана переменная локального типа; она не относится к глобальному типу/интерфейсу ServerData
. Ваша декларация фактически эквивалентна
function foo<T>(x: T): number { return x.foo }
Здесь яснее, что неизвестно, есть ли у объекта x
поле foo
.
Чего вы, вероятно, хотите, так это
function foo(x: ServerData): number { return x.foo }
Теперь движок типов знает, что поле foo
включено x
. Однако вы получите еще одну ошибку, так как поле foo
в ServerData
является строкой, но вы объявили, что функция foo
возвращает число.