Javascript 使用泛型定义函数

Javascript 使用泛型定义函数,javascript,typescript,Javascript,Typescript,有这样一个简单的代码: interface ServerData { foo: string bar: number } const oo = { foo: "abc", bar: 887 } function foo<ServerData>(x: ServerData): number { return x.foo } 这很奇怪,因为上面已经定义了ServerData接口。发生了什么?这是因为在函数上定义的泛型类型ServerData可能没

有这样一个简单的代码:

interface ServerData {
  foo: string
  bar: number
}

const oo = {
  foo: "abc",
  bar: 887
}

function foo<ServerData>(x: ServerData): number { return x.foo }

这很奇怪,因为上面已经定义了
ServerData
接口。发生了什么?

这是因为在函数上定义的泛型类型
ServerData
可能没有属性
foo
(泛型和接口不是一回事,您必须告诉编译器)

在代码中,您没有对编译器说泛型具有此属性。在您的情况下,您可以完全像这样摆脱泛型(由于函数返回一个数字,您还必须将
foo
转换为一个数字):

或者,您可以告诉编译器,函数中的泛型类型实现
ServerData
接口,如下所示:

function foo<T extends ServerData>(x: T): number { return Number(x.foo) }

对@WilsonPena回答的补充

foo
函数的声明中
ServerData
是一个局部类型变量;它不是指全局类型/接口
ServerData
。你的声明实际上相当于

函数foo(x:T):编号{return x.foo}
这里更清楚的是,不知道对象
x
是否有一个字段
foo

你可能想要的是

函数foo(x:ServerData):编号{return x.foo}
现在类型引擎知道
x
上有一个字段
foo
。但是,您将得到另一个错误,因为
ServerData
中的
foo
字段是一个字符串,但您已声明函数
foo
返回一个数字

function foo(x: ServerData): number { return Number(x.foo) }
function foo<T extends ServerData>(x: T): number { return Number(x.foo) }
function foo<T extends {foo: string}>(x: T): number { return Number(x.foo) }