Typing Functions
TypeScript 的类型推断可以帮助您做很多事,但是还有很多其他方法可以
提供更丰富的标记函数形状的方法。
可选函数是看起来很棒的一点,它可以让其他人知道你可以跳过这个参数。
// 嵌入函数接口可能很难阅读(可能有很多箭头)。使用类型别名可以
为函数参数命名
let i = 0;
const incrementIndex = (value?: number) => {
i += value === undefined ? 1 : value;
};
// 这个函数可以像这样调用:
incrementIndex();
incrementIndex(0);
incrementIndex(3);
// 你可以将参数标记为函数,从而在编写函数时提供类型推导。
const callbackWithIndex = (callback: (i: number) => void) => {
callback(i);
};
// 将鼠标悬停在上面的 index 上,您可以看到 TypeScript 可以正确
推断出 index 是一个 number 类型。
将函数作为实例的引用传递时,TypeScript 类型推导也可以正常工作。
为了展示这一点,我们会使用一个将 number 转换为 string 的函数:
type NumberCallback = (i: number) => void;
const callbackWithIndex2 = (callback: NumberCallback) => {
callback(i);
};
// 他们可以像这样调用:
callbackWithIndex((index) => {
console.log(index);
});
// 它可以适用于数组的 map 之类的方法中,比如将所有数字转换为字符串。
如果您将鼠标悬停在下面的 stringedNumbers 上,则可以看到期望的类型。
const numberToString = (n: number) => {
return n.toString();
};
// 您的函数可能可以接受许多类型,但是您可能只对其中一部分属性感兴趣。
而类型签名中的索引签名(indexed signature)对这种情况很有用。
以下类型声明此函数可以用于所有对象,只要它包含属性 name 即可:
const stringedNumbers = [1, 4, 6, 10].map((i) => numberToString(i));
// 我们可以使用快捷形式直接传递函数,并通过更简洁的代码获得相同的结果:
const stringedNumbersTerse = [1, 4, 6, 10].map(numberToString);
// 如果您希望了解更多关于索引签名的内容,我们建议访问以下链接:
https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks
https://basarat.gitbooks.io/typescript/docs/types/index-signatures.html
您还可以通过 tsconfig 配置中 suppressExcessPropertyErrors
的选项来在任何地方允许这种行为——但是您不知道其他使用您 API 的用户
是否关掉了这个选项。
JavaScript 中的函数可以接受不同的参数。有两种常见的模式来描述:用于
参数和返回值的并集类型以及函数重载。
只有在仅有一两处不同且不需要在不同函数中展示不同的文档时,才适合在
参数中使用并集类型。
interface AnyObjectButMustHaveName {
name: string;
[key: string]: any;
}
const printFormattedName = (input: AnyObjectButMustHaveName) => {};
printFormattedName({ name: "joey" });
printFormattedName({ name: "joey", age: 23 });
// 如果这是您第一次看到 declare 关键字,它使您可以告诉 TypeScript
文件中某些即使在运行时不存在的东西存在,对于映射有副作用的代码或
实现某些东西需要很多代码的 demo 来说都非常有用。
const boolOrNumberFunction = (input: boolean | number) => {};
boolOrNumberFunction(true);
boolOrNumberFunction(23);
// 另一方面,函数重载为参数和返回类型提供了丰富的语法。
interface BoolOrNumberOrStringFunction {
/** 接受一个 bool,返回一个 bool */
(input: boolean): boolean;
/** 接受一个 number,返回一个 number */
(input: number): number;
/** 接受一个 string,返回一个 bool */
(input: string): boolean;
}
// 函数重载对您很有帮助,但是还有一种可以处理不同类型的输入
和返回值的工具,那就是泛型。
这为您提供了一种在类型定义中将类型作为占位符变量的方法。
example:generic-functions
example:function-chaining
declare const boolOrNumberOrStringFunction: BoolOrNumberOrStringFunction;
const boolValue = boolOrNumberOrStringFunction(true);
const numberValue = boolOrNumberOrStringFunction(12);
const boolValue2 = boolOrNumberOrStringFunction("string");
// 将鼠标悬停在上述值和函数上,您可以看到正确的文档和返回值。