函数
TypeScript 函数
函数类型在
参数注解
let stories: [string, string[]][] = [];
function addStory(title: string, tags: string[]): void {
stories.push([title, tags]);
}
同样可以在
let sortByLength: (x: string, y: string) => number = (x, y) =>
x.length - y.length;
tags.sort(sortByLength);
也可以在函数参数中指定可选参数:
function storySummary(title: string, description?: string) {
if (description) {
return title + description;
} else {
return title;
}
}
或者使用默认值:
function storySummary(title: string, description: string = "") {
return title + description;
}
值得一提的是,当我们确定某个函数并不返回值时,需要注意不能使用
function fn(x: () => void) {
const k = x(); // oops! meant to do something else
k.doSomething(); // error, but would be OK if the return type had been 'any'
}
函数重载
declare function createStore(
reducer: Reducer,
preloadedState: PreloadedState,
enhancer: Enhancer
);
declare function createStore(reducer: Reducer, enhancer: Enhancer);
该特性可以帮我们优化代码,譬如:
function padding(a: number, b?: number, c?: number, d?: any) {
if (b === undefined && c === undefined && d === undefined) {
b = c = d = a;
} else if (c === undefined && d === undefined) {
c = a;
d = b;
}
return {
top: a,
right: b,
bottom: c,
left: d
};
}
如果仔细查看代码,就会发现
// 重载
function padding(all: number);
function padding(topAndBottom: number, leftAndRight: number);
function padding(top: number, right: number, bottom: number, left: number);
// Actual implementation that is a true representation of all the cases the function body needs to handle
function padding(a: number, b?: number, c?: number, d?: number) {
if (b === undefined && c === undefined && d === undefined) {
b = c = d = a;
} else if (c === undefined && d === undefined) {
c = a;
d = b;
}
return {
top: a,
right: b,
bottom: c,
left: d
};
}
padding(1); // Okay: all
padding(1, 1); // Okay: topAndBottom, leftAndRight
padding(1, 1, 1, 1); // Okay: top, right, bottom, left
padding(1, 1, 1); // Error: Not a part of the available overloads
函数类型注解
我们可以使用类型别名或者接口来表示一个可被调用的类型注解:
interface ReturnString {
(): string;
}
它可以表示一个返回值为
declare const foo: ReturnString;
const bar = foo(); // bar 被推断为一个字符串。
一个接口可提供多种调用签名,用以特殊的函数重载:
interface Overloaded {
(foo: string): string;
(foo: number): number;
}
// 实现接口的一个例子:
function stringOrNumber(foo: number): number;
function stringOrNumber(foo: string): string;
function stringOrNumber(foo: any): any {
if (typeof foo === 'number') {
return foo * foo;
} else if (typeof foo === 'string') {
return `hello ${foo}`;
}
}
const overloaded: Overloaded = stringOrNumber;
// 使用
const str = overloaded(''); // str 被推断为 'string'
const num = overloaded(123); // num 被推断为 'number'
这也可以用于内联注解中:
let overloaded: {
(foo: string): string;
(foo: number): number;
};
Generator | 生成器
function* numbers(): IterableIterator<number> {
console.log("Inside numbers; start");
yield 1;
console.log("Inside numbers; after the first yield");
yield 2;
console.log("Inside numbers; end");
}
// 迭代器结果的类型声明
interface IteratorResult<CompletedType, SuspendedType> {
value: CompletedType | SuspendedType;
done: this is { value: CompletedType };
}