在接口中使用粗箭头和非粗箭头语法声明函数有什么区别?
What's the difference between declaring functions using the fat arrow and non-fat arrow syntax in interfaces?
在 TypeScript 的接口和类型中使用粗箭头和非粗箭头语法声明函数有什么区别?
例如:
build(paramOne: string): string;
相比于:
build: (paramOne: string) => string;
起初,我以为它会限制我实现功能的方式,但事实并非如此。所以,我认为它与 ES6 中的 this
无关。但是我确实注意到,当我尝试重载时,用粗箭头语法声明的那个有问题。
例如,这是不可接受的:
build: (paramOne: string) => void
build: (paramOne: number, paramTwo: string) => void
这会产生错误:
Subsequent property declarations must have the same type. Property 'build' must be of type '{ (paramOne: string): string; (paramOne: number, paramTwo: string): number; }', but here has type '(params: unknown) => void
但这没关系:
build(paramOne: string): string;
build(paramOne: number, paramTwo: string): number;
那么,这两种语法是否相同?是否有任何差异或场景我应该使用一个而不是另一个?
主要区别在于带箭头语法的是 function type expression, while the other is a call signature。明显的区别是语法,来自手册:
Note that the syntax is slightly different compared to a function type expression - use : between the parameter list and the return type rather than =>.
您是正确的,此语法不会使函数的 this
成为词法范围。您可以指定您希望函数在调用时具有的任何 this
类型:
thisChanged: (this: { test: number }, param1: number, param2: boolean) => string;
不过你也猜对了,在应用上有细微的差别。请注意术语 expressions 而不是 signatures。前者“评估”为一个调用签名,除非定义为表达式的交集,而后者可以多次定义以创建 function overloads:
//multiple call signatures used for function overloading:
function build(param1: string) : string;
function build(param1: number) : string;
function build(param1: string | number) {
return param1.toString();
}
//intersection of expressions
type build2 = ((param1:string) => string) & ((param1:number) => string);
declare const b: build2;
b(2) //OK
b("test") //OK
b(false) //No overload matches this call.
应用于您在 object types 中使用它们的用例,可以在同一键下多次指定调用签名,因为这会导致多个函数重载。另一方面,[key]: <function expression>
语法定义了一个具有函数表达式类型值的 属性(因此无法多次指定 属性 作为键必须是唯一的)。
另请注意,推断类型对应于函数的定义方式(作为函数声明或表达式):
//call signature: function build3(param1: string | number): string
function build3(param1: string|number) : string {
return param1.toString();
}
//function expression: const build4: (param1: string | number) => string
const build4 = (param1: string|number) : string => param1.toString();
在 TypeScript 的接口和类型中使用粗箭头和非粗箭头语法声明函数有什么区别?
例如:
build(paramOne: string): string;
相比于:
build: (paramOne: string) => string;
起初,我以为它会限制我实现功能的方式,但事实并非如此。所以,我认为它与 ES6 中的 this
无关。但是我确实注意到,当我尝试重载时,用粗箭头语法声明的那个有问题。
例如,这是不可接受的:
build: (paramOne: string) => void
build: (paramOne: number, paramTwo: string) => void
这会产生错误:
Subsequent property declarations must have the same type. Property 'build' must be of type '{ (paramOne: string): string; (paramOne: number, paramTwo: string): number; }', but here has type '(params: unknown) => void
但这没关系:
build(paramOne: string): string;
build(paramOne: number, paramTwo: string): number;
那么,这两种语法是否相同?是否有任何差异或场景我应该使用一个而不是另一个?
主要区别在于带箭头语法的是 function type expression, while the other is a call signature。明显的区别是语法,来自手册:
Note that the syntax is slightly different compared to a function type expression - use : between the parameter list and the return type rather than =>.
您是正确的,此语法不会使函数的 this
成为词法范围。您可以指定您希望函数在调用时具有的任何 this
类型:
thisChanged: (this: { test: number }, param1: number, param2: boolean) => string;
不过你也猜对了,在应用上有细微的差别。请注意术语 expressions 而不是 signatures。前者“评估”为一个调用签名,除非定义为表达式的交集,而后者可以多次定义以创建 function overloads:
//multiple call signatures used for function overloading:
function build(param1: string) : string;
function build(param1: number) : string;
function build(param1: string | number) {
return param1.toString();
}
//intersection of expressions
type build2 = ((param1:string) => string) & ((param1:number) => string);
declare const b: build2;
b(2) //OK
b("test") //OK
b(false) //No overload matches this call.
应用于您在 object types 中使用它们的用例,可以在同一键下多次指定调用签名,因为这会导致多个函数重载。另一方面,[key]: <function expression>
语法定义了一个具有函数表达式类型值的 属性(因此无法多次指定 属性 作为键必须是唯一的)。
另请注意,推断类型对应于函数的定义方式(作为函数声明或表达式):
//call signature: function build3(param1: string | number): string
function build3(param1: string|number) : string {
return param1.toString();
}
//function expression: const build4: (param1: string | number) => string
const build4 = (param1: string|number) : string => param1.toString();