深入函数:函数重载、this 和 as const
函数重载(overload)
重载允许一个函数在接受不同数量或类型的参数时,作出不同的处理
1 | function createDate(n: number): Date; |
关于函数重载:
- 重载的思想来自于 Java 或 C#,因为它们都不支持联合类型
- 重载是为了使同名函数可以接受不同类型的参数
- 不是非得使用重载,即使不用函数重载也可以实现上述的功能
1
2
3
4
5
6
7
8
9function createDateFromNumber(n: number): Date {
return new Date(n);
}
function createDateFromYMD(year: number, month: number, date: number): Date {
return new Date(year, month, date);
}
createDateFromNumber(1677772800000);
createDateFromYMD(2023, 2, 3); - 复杂度守恒,你不可能把复杂度凭空抹除掉,因此你只能选择把复杂度留给自己或者抛给用户。比如上面的例子中,使用函数重载就是把复杂度留给自己;而提供两个函数供用户选择就是把复杂度留给用户。
- 箭头函数不支持函数重载,箭头函数是匿名函数,无法定义多个同名的箭头函数,应该使用传统的函数声明或函数表达式。
举例
使用 TypeScript 的函数重载和类型谓词来处理具有不同属性的组件 props
1 | interface PropsA { |
1 | // isA 为 true 时,props 类型为 PropsA,a1、a2、a3 都必传 |
这种模式允许你在同一个组件中安全地处理不同的属性集,同时保持类型的严格性和清晰性。
指定 this 的类型
1 | type Person = { name: string }; |
剩余参数
1 | function sum(name: string, ...array: number[]) { |
注意,剩余参数只能是最后一个参数
展开参数
1 | function sum(...array: number[]) { |
常量断言(as const)
TS 会区别对待可修改和不可修改的值的类型推断
例如下面的 immutableString
会被推断成单值类型 'ClariS'
而 mutableString
则会被推断成通用的 string
类型
1 | const immutableString = 'ClariS'; // 'ClariS' |
而在一般的对象中,由于对象的属性都具有可修改性,TS 都会对它们「从宽」类型推断,例如下面的 prop
的类型被推断为 string
1 | const obj = { |
根本原因在于 TS 会根据一个值在后续的逻辑中是否可能被修改而给出不同的类型推断结果:
- 对于有可能被修改的值,TS 采用较为宽松的类型推断策略,即把上述
mutableString
,obj.props
推断为较为宽泛的string
类型,这使未来可能出现的赋值具有更大的灵活度 - 对于不可能被重新赋值的值,TS 采用较为严格的类型推断策略,即把上述
immutableString
推断为单值类型'ClariS'
,这样未来把immutableString
赋值给别的变量时,出现类型检查错误的可能性更小
关于这部分内容,详细可参考文章TypeScript夜点心:类型推断的策略
TS 常量断言
常量断言可以把一个值标记为一个不可篡改的常量,从而让 TS 以最严格的策略来进行类型推断
还是使用上述的例子,给他们分别加上 as const
后类型推断如下
1 | let mutableString = 'vivy' as const; // 'vivy' |
再看看其他的例子
1 | const array1 = [1, 'hi']; // (string | number)[] |
从以上例子中可以看出,as const
会把类型推窄,并给类型加上 readonly
关于这部分内容,详细可参考文章TypeScript 夜点心:常量断言
const 与 as const 的区别
as const
中的 const
与我们声明常量时使用的 const
有什么区别呢?
其实两者无论是语法还是语义,都相当不同:
const
常量声明是 ES6 的语法,对 TS 而言,它只能反映该常量本身是不可被重新赋值的,它的子属性仍然可以被修改,故 TS 只会对它们做松散的类型推断as const
是 TS 的语法,它告诉 TS 它所断言的值以及该值的所有层级的子属性都是不可篡改的,故对每一级子属性都会做最严格的类型推断
more about the function
完整示例
1 | type Config = { |
类型 Config
可以写在左边,也可以写在右边
void 返回值类型
1 | function f1(): void { |