函数

2022-08-24  本文已影响0人  苍老师的眼泪

函数类型表达式

let f: (a: number, b: number) => number

f = function(x: number, y: number) {
   return x + y
}

// 具有 void 返回类型的上下文函数类型
type vf = () => void

// 并不要求函数不返回值
const f1:vf = function() {
   return 20
}

// 该返回值不会被忽略
console.log(f1())   // 20

// 但是具有 void 类型: 不能将类型“void”分配给类型“number”
let num:number = f1() 

// 函数字面量定义了 void 返回类型时,必须不能返回任何值
function f2():void {
   return 10
}

// never 表示永远不会被观察到的值
function f2(): never {
   throw new Error('抛出异常') // 永远不会返回结果
}

调用签名

type descripableFunction = {
    greet: string,
    (argc1: string): void
}

function f(greet: descripableFunction, name: string) {
    greet(name)
}

const g: descripableFunction = (name: string) => {
    console.log(name + ', ' + g.greet)
}

// 需要的属性可以后面再加
g.greet = 'How are you?'

f(g, 'Edison')

构造签名

class Car {
    color: string;
    constructor(color: string) {
        this.color = color
    }
}

type car_factory = {
    new (color: string): Car
}

function produce_car(manufactor: car_factory, color: string) {
    return new manufactor(color)
}

const car1 = produce_car(Car, 'red')
console.log(car1.color)

泛型函数

输入类型与输出类型有关,或者两个输入类型以某种方式关联
根据参数类型判断出泛型的实际类型

// T 是代表被推断的类型的名字, 可以是其他自定义名称
function first_element<T>(arr: T[]): T {
    return arr[2]
}

// 数组会被 ts 推断出具有 number[] 类型, 所以这里推断出 T 是 number
first_element([1,2,3])
// 所以以上相当于
first_element<number>([1,2,3])

// 这里的数组有各种值,但还是可以通过编译运行
first_element([1, false, 'asdf'])
// 因为以上以上相当于, T 被推到为 any
first_element<any>([1, false, 'asdf'])



// 多个推断类型
function map<Input, Output>(inputs: Input[], reflect: (input: Input) => Output): Output[] {
    return inputs.map(e => reflect(e))
}

let result = map(['1', '2', '3'], parseInt)

console.log(result)



// 类型限制:推断的类型必须继承一个具有 length 属性的对象
function longest<T extends { length: number }>(a: T, b: T) {
    if (a.length > b.length)
        return a
    else
        return b
}

const longestArr = longest([1,2,3], [1,2])
const longestStr = longest('Edison', 'Kingway')



// 指定类型
function combine<T>(arr1: T[], arr2: T[]) : T[] {
    return arr1.concat(arr2)
}

// 这个时候会报错,因为 T 已经从 arr1 推导出为 number, 然而 arr2 又为 string[]
// combine([1,2,3], ['a', 'b', 'c'])

// 解决方法:手动指定 T 的类型
combine<number | string>([1,2,3], ['a', 'b', 'c'])


// 实参展开
const argc1 = [1, 2]

// argc1 的类型被推断为: number[]
// atan2 只接收两个参数,它认为 number[] 不符合参数设定
Math.atan2(...argc1)


const argc2 = [1, 2] as const

Math.atan2(...argc2)
上一篇下一篇

猜你喜欢

热点阅读