Generic function types 泛型函数参数
为什么需要泛型函数参数
大多数情况下,我们函数参数可能是一种类型比如 string 和 number 。但有时候,编写函数时需要从输入类型参数传递到输出。
定义泛型函数参数
const createRow = <T,>(label: string, value: T, disabled = false) => ({
//...
});
为了区别JSX语法,即使是一个泛型变量类型,后面也建议带上(逗号,)标识
// Thing 1: Start of JSX
const createRow = <T>Some JSX stuff!</T>;
// Thing 2: start of generic function
const createRow = <T>(someArg: T) => {
/* some function stuff */
}
相关例题
定义一个函数
const mapArray = (arr, fn) => arr.map(fn);
满足下面测试用例
import { Expect, Equal } from 'type-testing';
const strings = ['1', '1', '2', '3', '5'];
const numbers = [1, 1, 2, 3, 5];
const stringsToNumbers = mapArray(strings, str => parseInt(str));
expect(stringsToNumbers).toEqual(numbers);
type test_stringsToNumber = Expect<Equal<
typeof stringsToNumbers,
number[]
>>;
const numbersToStrings = mapArray(numbers, num => `${num}`);
expect(numbersToStrings).toEqual(strings)
type test_numbersToStrings = Expect<Equal<
typeof numbersToStrings,
string[]
>>;
const numbersToNumbers = mapArray(numbers, num => num + 1);
expect(numbersToNumbers).toEqual([2, 2, 3, 4, 6])
type test_numbersToNumbers = Expect<Equal<
typeof numbersToNumbers,
number[]
>>;
const stringsToStrings = mapArray(strings, str => `${str}!`);
expect(stringsToStrings).toEqual(['1!', '1!', '2!', '3!', '5!'])
type test_stringsToStrings = Expect<Equal<
typeof stringsToStrings,
string[]
>>;
例题解析
arr很明显入参一定是数组类型, 所以可以像下面定义;
const mapArray = <Arr,>(arr:Arr[],fn)=>arr.map(fn);
可以发现fn函数参数,实际就是把第一参数arr传进来,所以只要去arr类型变量就可以了, 但是函数输出实际与输入是没有关系的,就不能在使用原来Arr泛型类型。
最后mapArray被定义如下:
const mapArray = <Arr,Result>(arr:Arr[],fn:(arg:Arr)=> Result)=>arr.map(fn);
Generic Type Constraints 泛型类型约束
定义泛型变量后,就允许我们在调用泛型的时候确定类型了,但有时候,我们需要对泛型进行约束:
这里给出一个例子,定义两个函数,一个用联合类型,一个是泛型函数参数。
-
对于drive,来说非泛型类型变量,它的CardType类型是固定的;
-
但对于T,泛型变量类型来说,由于默认没有约束 它可以传任何值,这种函数参数肯定是不符合我们期望的,所以我们必须对泛型变量做约束。
对泛型类型做约束 ,我们在泛型类型后面添加 extends CarType 就能对泛型类型做了指定约束了