泛型函数

  1. /* 泛型函数 */
  2. // 通过函数名后加<T>,表示该函数是一个泛型函数
  3. // valeus可以是任意类型T
  4. // 返回的数组中的元素类型是T
  5. function createArray_4101<T>(value: T, length: number): T[]{
  6. let arr = []
  7. for (let i = 0; i < length; i++) {
  8. arr[i] = value
  9. }
  10. return arr
  11. }
  12. // 使用函数时,通过<...>来确认输入的类型
  13. let fooArray_4101 = createArray_4101<string>('foo', 3)
  14. console.log(fooArray_4101) // [ 'foo', 'foo', 'foo' ]
  15. let fooArray_4102 = createArray_4101<number>(9, 3)
  16. console.log(fooArray_4102) // [ 9, 9, 9 ];
  17. // 非泛型函数无得取得内部值的类型方法,但通过泛型可以获取
  18. fooArray_4102.push(1)

image.png

答案

C

解析

函数 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[];  //  报错

image.png

答案

A

解析

泛型的作用域是局部的而不是全局的。比如我们在泛型函数或泛型类中使用泛型,那么我们就只能在内部使用,而不能在外部使用。泛型函数和泛型类中泛型的(局部)作用域是块级作用域。内部闭环,离开函数或者类则无法访问。
泛型类将在后面的章节讲到。

泛型中的类型推论

/* 泛型的类型推论 */
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>

image.png

答案

B

解析

函数 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' ]

image.png

答案

number
string

解析

本题目比较简单,多泛型参数显示指定参数类型。函数 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[]

image.png

答案

number
string

解析

在函数 animalInfo 中已经指定了泛型的默认值 T 为 number,R 为 string.
在第一次调用中并没有传参数,因此泛型 T 是默认类型 number。
animalInfo()
在第二次调用中,第一个参数指定了类型为 string,因此泛型 T 是的类型为 string。
animalInfo(‘10’, ‘panda’);