我正在学习Typescript,并且阅读了两种编写函数类型的方法:带有粗箭头或带有对象文字。
例如:
let myAdd1: (x: number, y: number) => number =
function(x: number, y: number): number {return x + y; };
let myAdd2: { (x: number, y: number): number } =
function(x: number, y: number): number {return x + y; };
使用一个而不使用另一个的原因是什么?
感谢您的回答。
答案 0 :(得分:1)
第一个示例是普通的类型化函数声明和赋值。第二个示例使用函数重载速记。
考虑我们有一些正常的函数重载:
function myMultiAdd(x: number, y: number): number;
function myMultiAdd(x: number, y: number, z?: number): number {
return x + y + (z ? z : 0);
}
myMultiAdd(1, 2)
和myMultiAdd(1, 2, 3)
都可以使用。在有许多函数重载的情况下使用此模式很不方便,因为我们会一次又一次地重复相同的名称,因此,打字稿具有如下简短的函数重载语法:
let myMultiAdd: {
(x: number, y: number): number,
(x: number, y: number, z: number): number
} = function (x: number, y: number, z?: number): number {
return x + y + (z ? z : 0);
}
因此,如果您不想使用函数重载,则应该始终使用第一个示例来键入函数。
答案 1 :(得分:1)
这些是用不同方式编写的相同类型:
let myAdd1: (x: number, y: number) => number;
type Func = typeof myAdd1;
// type Func = (x: number, y: number) => number
let myAdd2: { (x: number, y: number): number };
type Callable = typeof myAdd2;
// type Callable = (x: number, y: number) => number
您可以看到编译器认为Func
和Callable
均为(x: number, y: number) => number
类型。由于它们是相同的,因此偏爱彼此的原因可能是主观的和基于观点的。
但是,如果您开始向函数添加属性,则对象表示法可能更可取,因为它更易于表示:
let func1: ((x: string) => string) & { color: string } =
Object.assign((z: string) => z.toUpperCase(), { color: "red" });
type FuncWithProp = typeof func1;
// type FuncWithProp = ((x: string) => string) & { color: string; }
let func2: { (x: string): string; color: string } =
Object.assign((z: string) => z.toLowerCase(), { color: "green" });
type CallableWithProp = typeof func2;
// type CallableWithProp = { (x: string): string; color: string }
类型FuncWithProp
和CallableWithProp
不再被认为是相同的,但是它们是可以相互分配的(意味着编译器认为彼此extends
是彼此相同的):
type MutuallyExtends<T extends U, U extends V, V = T> = void;
type FuncVsCallableWithprops = MutuallyExtends<FuncWithProp, CallableWithProp>; // okay
因此,原则上您也可以使用其中任何一个,但是FuncWithProp
是intersection type,而CallableWithProp
是单个对象类型,在某些情况下可能会表现更好。
好的,希望能有所帮助;祝你好运!