当前位置:   article > 正文

TypeScript基础篇 - TS的函数_ts 函数怎么写

ts 函数怎么写

目录

构造函数表达

泛型和函数

泛型函数

Contextual Typing【上下文映射,上下文类型】

泛型约束

手动指定类型

泛型的使用规范

对比

可选参数

思考:onClick中e的设计

函数重载

修改办法

操作符重载

THIS

void【空返回值】

思考为什么这样写?

Rest params

小结


构造函数表达

  1. type SomeConstructor = {
  2. new (s: int):String
  3. }
  4. function fn(ctor: SomeConstructor) {
  5. return new ctor("hello")
  6. }
  7. const str = fn(String)
  8. console.log(str) // hello

泛型和函数

泛型函数

  1. function firstElement<Type>(arr: Type[]):Type {
  2. return arr[0]
  3. }

Contextual Typing【上下文映射,上下文类型】

  1. // map : a -> b
  2. function map<Input, OutPut>(arr: Input[], func: (arg: Input) => Output): Output[] {
  3.   return arr.map(func); // Output[]
  4. }
  5. const parsed = map(["1", "2", "3"], (n) => parseInt(n))
  6. // [1,2,3]

泛型约束

  1. function minimumLength<Type extends { length: number }>(
  2.   obj: Type,
  3.   minimum: number
  4. ): Type {
  5.   if (obj.length >= minimum) {
  6.     return obj;
  7.   } else {
  8.     return { length: minimum };
  9.     // 不能将类型“{ length: number; }”分配给类型“Type”。
  10.     // "{ length: number; }" 可赋给 "Type" 类型的约束,
  11. // 但可以使用约束 "{ length: number; }" 的其他子类型实例化 "Type"
  12.   }
  13. }

手动指定类型

  1. function combine<Type>(arr1: Type[], arr2: Type[]):Type[] {
  2. return arr1.concat(arr2);
  3. }
  4. const arr = combine([1,2,3], ["hello"]);// Error 不能将类型“string”分配给类型“number”。
  5. const arr2 = combine<string | number>([1,2,3],["hello"]) // 手动指定string | number

泛型的使用规范

  1. // 泛型的参数越简化越好,最少支持原则,高效,参数少
  2. function firstElement1<Type>(arr: Type[]) { // 更简单 √,方便阅读
  3.   return arr[0];
  4. }
  5. function firstElement2<Type extends any[]>(arr: Type) {
  6.   return arr[0]
  7. }

对比

对比下一组,哪个更好?

  1. function filter1<T>(arr: T[], func: (arg: T) => boolean): T[] {
  2. // √ 泛型参数少,读起来方便
  3.   return arr.filter(func);
  4. }
  5. function filter2<T, Func extends (arg: T) => boolean>(arr: T[], func: Func): T[] {
  6. // Func这个泛型没有必要
  7.   return arr.filter(func);
  8. }

可选参数

  1. function myForEach(arr: any[], callback: (arg: any, index?:number)=> void){
  2. // 可选参数index?:
  3. for (let i = 0; i < arr.length; i++) {
  4. callback(arr[i], i);
  5. }
  6. }
思考:onClick中e的设计
  1. <div onClick={ e=>{} }></div> // e是可选参数
  2. <div onClick={ ()=>{} }></div> // e是可选参数

函数重载

  1. function add3<T> (a: T, b: T ) {
  2. return a + b // Error 运算符“+”不能应用于类型“T”和“T”。
  3. }
  4. // a,b不一定可以相加
  5. // 函数的重载,可多次,基础方法
  6. function add(a:number,b:number); // add(1,2)
  7. function add(a:string,b:string); // add("1","2")
  8. function add(a:number,b:string); // add(1,"2")
  9. function add(a:string,b:number); // add("1",2)
  10. function add(a:string); // add(1)
  11. function add(a: any,b?:any) {
  12. if(!b) {
  13. b = 1
  14. }
  15. return a + b
  16. }

修改办法

  1. function isSet<T>(x: any): x is Set<T> {
  2.   return x instanceof Set
  3. }
  4. function add(a: number, b: number): number;
  5. function add(a: string, b: string): string;
  6. function add<T>(a: Set<T>, b: Set<T>): Set<T>;
  7. function add<T>(a: T, b: T): T {
  8.   if (isSet<T>(a) && isSet<T>(b)) {
  9.     return new Set([...a, ...b]) as any
  10.   }
  11.   return (a as any) + (b as any)
  12. }
  13. const a = new Set<string>(["apple", "redhat"])
  14. const b = new Set<string>(["google", "ms"])
  15. console.log(add(a, b))
  16. console.log(add(1, 2))
  17. console.log(add("a", "k"))

操作符重载

THIS

  1. interface DB {
  2.   exec(sql: string) => any
  3. }
  4. function runSql(this: DB, sql: string) {
  5.   this.exec(sql)
  6. }
  7. runSql.bind(new DB()).("select * from user")

void【空返回值】

  1. // void
  2. type voidFunc = () => void;
  3. const f1: voidFunc = () => {
  4.   return true;
  5. }
  6. const f2: voidFunc = () => true
  7. const f3: voidFunc = function () {
  8.   return true;
  9. }

思考为什么这样写?

  1. function safeParse(s: string): unknown { // 比any安全
  2. return JSON.parse(s); // as 断言;断言之前,unknown值是不能直接赋值给其他变量的
  3. }

Rest params

  1. // JS本身有这个方法
  2. function multiply(n: number, ...m: number[]) {
  3.   return m.map((x) => n * x);
  4. }
  5. // 无法重新声明块范围变量“a”。
  6. const a = multiply(10, 1, 2, 3, 4);

小结

  • 重新思考泛型的作用?提供对共性的抽象,// add , filter
  • 思考函数重载的意义?为函数提供了更严格的类型检查方式,能让真正使用any这样的函数,作为参数,把它窄化,更精确的类型去表达,所有函数调用的类型都是准确的
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号