用打字稿写函数类型:粗箭头和对象文字类型

时间:2019-12-13 14:01:36

标签: typescript

我正在学习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; };

使用一个而不使用另一个的原因是什么?

感谢您的回答。

2 个答案:

答案 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

您可以看到编译器认为FuncCallable均为(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 }

类型FuncWithPropCallableWithProp不再被认为是相同的,但是它们是可以相互分配的(意味着编译器认为彼此extends是彼此相同的):

type MutuallyExtends<T extends U, U extends V, V = T> = void;
type FuncVsCallableWithprops = MutuallyExtends<FuncWithProp, CallableWithProp>; // okay

因此,原则上您也可以使用其中任何一个,但是FuncWithPropintersection type,而CallableWithProp是单个对象类型,在某些情况下可能会表现更好。


好的,希望能有所帮助;祝你好运!

Link to code