泛型函数
/* 泛型函数 */
// 通过函数名后加<T>,表示该函数是一个泛型函数
// valeus可以是任意类型T
// 返回的数组中的元素类型是T
function createArray_4101<T>(value: T, length: number): T[]{
let arr = []
for (let i = 0; i < length; i++) {
arr[i] = value
}
return arr
}
// 使用函数时,通过<...>来确认输入的类型
let fooArray_4101 = createArray_4101<string>('foo', 3)
console.log(fooArray_4101) // [ 'foo', 'foo', 'foo' ]
let fooArray_4102 = createArray_4101<number>(9, 3)
console.log(fooArray_4102) // [ 9, 9, 9 ];
// 非泛型函数无得取得内部值的类型方法,但通过泛型可以获取
fooArray_4102.push(1)
答案
解析
函数 animalInfo 的返回值为
{ age: arg, name: ‘panda’ }
所以只需要确定变量 arg 的类型即可。arg 参数中已经确定了泛型 T。所以答案选 C。
泛型的作用域
/* 泛型的作用域 */
function createArray_4102<T>(value: T, length: number): T[] {
let arr = [] // 默认是any[]类型
for (let i = 0; i < length; i++) {
arr[i] = value
}
return arr
}
// 通过在函数内部使用<T>来确认arr的类型
function createArray_4103<T>(value: T, length: number): T[] {
let arr: T[] = [] // 则为是T[]类型
for (let i = 0; i < length; i++) {
arr[i] = value
}
return arr
}
// 注意:函数外部无法使用<T>
let foo_4103: T[]; // 报错
答案
解析
泛型的作用域是局部的而不是全局的。比如我们在泛型函数或泛型类中使用泛型,那么我们就只能在内部使用,而不能在外部使用。泛型函数和泛型类中泛型的(局部)作用域是块级作用域。内部闭环,离开函数或者类则无法访问。
泛型类将在后面的章节讲到。
泛型中的类型推论
/* 泛型的类型推论 */
function createArray_4104<T>(value: T, length: number): T[] {
let arr: T[] = []
for (let i = 0; i < length; i++) {
arr[i] = value
}
return arr
}
let fooArray_4104 = createArray_4104('foo', 3) // 删除<...>依旧推论为<string>
答案
解析
函数 animalInfo 的返回值类型为
{ age: T; name: string; }
泛型 T 的类型为函数 animalInfo 的参数类型。
const animal = animalInfo(10);
所以变量 animal 的类型为 number。
多个类型参数
/* 多个类型参数 */
// 此时推论为输入的是any输出的是any[]
function swap_4105(tuple) {
return [tuple[1], tuple[0]]
}
let swapped_4105 = swap_4105(['foo', 7]) // [ 7, 'foo' ]
// 添加多个泛型参数
function swap_4106<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]]
}
// 此时可以定义输入的类型,如果不定义也会自动推论出<string, number>
let swapped_4106 = swap_4106<string, number>(['foo', 7]) // [ 7, 'foo' ]
let swapped_4107 = swap_4106(['foo', 7]) // [ 7, 'foo' ]
答案
解析
本题目比较简单,多泛型参数显示指定参数类型。函数 animalInfo 的两个参数类型分别是 number 和 string。所以本题的答案为 number 和 string。
默认类型
/* 默认类型 */
// 如果希望这个函数默认不传入参数(即agruements.length为0)
function createArray_4107<T>(value?: T, length?: number): T[] {
if( arguments.length === 0){
return []
}
let arr: T[] = []
for (let i = 0; i < length; i++) {
arr[i] = value
}
return arr
}
let fooArray_4107 = createArray_4107() // 泛型被推论为未知<unknown>,返回值也是unknown[]
// 第一种方式指定泛型
let fooArray_4108 = createArray_4107<string>() // 泛型被推论为<string>,返回值也是string[]
// 第二种使用默认类型
function createArray_4108<T = string>(value?: T, length?: number): T[] {
if (arguments.length === 0) {
return []
}
// ..
}
let fooArray_4109 = createArray_4108() // 泛型被推论为<string>,返回值也是string[]
答案
解析
在函数 animalInfo 中已经指定了泛型的默认值 T 为 number,R 为 string.
在第一次调用中并没有传参数,因此泛型 T 是默认类型 number。
animalInfo()
在第二次调用中,第一个参数指定了类型为 string,因此泛型 T 是的类型为 string。
animalInfo(‘10’, ‘panda’);