最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • TypeScript 的 Substitutability

    正文概述 掘金(泡泡机不冒泡了)   2021-01-26   511

    Substitutability 中文含义是 可代替性,这个词我未在 TypeScript 的语言特性相关文档上看到,百度、谷歌搜索也寥寥无几。仅在TypeScript FAQ 找到相关描述。

    这段描述很好理解,大体就是子类型可以用在父类型出现的地方。但实际涉及的TypeScript 使用场景,和这个词不是很契合,也许是语言的差异,中文含义不便于理解。

    实际 Substitutability 解决的场景是:TypeScript 允许 function 作为回调函数时,入参个数、返回类型可以不符合方法签名。

    回调 Function 入参比签名少

    fetchResults 有一个参数,即回调函数。 该方法从某处获取数据,然后执行回调。 回调的方法签名有两个参数, statusCoderesults

    function fetchResults(callback: (statusCode: number, results: number[]) => void) {
      const results = [1,2,3];
      ...
      callback(200, results); 
    }
    

    我们用下面的方式调用 fetchResults,注意方法签名是不同的,它没有第二个参数 results

    function handler(statusCode: number) {
      // 业务处理
      ...
    }
    
    fetchResults(handler); // ✔️
    

    可以正常编译,没有任何错误或警告。 看起来有点奇怪,但细想一下,你一直在这么用。

    Array.prototype.forEach 方法签名

        /**
         * Performs the specified action for each element in an array.
         * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
         * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
         */
        forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void
    

    实际使用:

    let items = [1, 2, 3];
    items.forEach(arg => console.log(arg));
    

    在运行时,forEach使用三个参数(value、index、array)调用给定的回调函数,但大多数时候回调函数只使用其中的一个或两个参数。

    那为什么不干脆将forEach 参数声明为可选。

    forEach(callback: (element?: T, index?: number, array?: T[]))
    

    如果声明为可选,由于回调的提供者不知道调用方何时会传递多少参数,将不得不检查各个参数,这显然不是你想要的。

    function maybeCallWithArg(callback: (x?: number) => void) {
        if (Math.random() > 0.5) {
            callback();
        } else {
            callback(42);
        }
    }
    

    声明非可选,是站在调用者的角度,保证按声明传递参数,可以兼容需要不同个数参数的回调函数;

    这么处理的合理性在于,回调函数自身是最了解如何处理入参的,如果它不关心某些入参,它可以安全的忽略。

    回调返回类型不匹配签名 return void

    如果函数类型指定返回类型 void,则也接受具有不同的、更具体的返回类型的函数。同样,用前面的例子,这次增加handle的返回类型声明。

    function handler(statusCode: number): {age:number}{
      //  业务处理
      ...
      return {"age": 4};
    }
    
    fetchResults(handler); // ✔️
    

    fetchResults 接受的回调函数返回类型是void,而这次的handler 返回{age:number}类型,依然正常编译。

    你依然可以将callback结果赋值给一个变量,但仅仅限于声明语句,其他操作都将编译失败。

    function fetchResults(callback: (statusCode: number, results: number[]) => void) {
      const results = [1,2,3];
      ...
      const didItWork = callback(200, results); // ✔️
      console.log(didItWork); // ✔️
      console.log(didItWork.age) // ❌
      didItWork = {"age": 4} ; // ❌
    }
    
    // 注意虽然编译报错,但不影响最后js执行,Playground 运行结果
    [LOG]: {
      "age": 4
    } 
    [LOG]: 4 
    

    这么处理的合理性在于,回调函数的调用者通过声明callback 返回void, 它最清楚也可以保证返回值不会被使用。

    示例Playground


    下载网 » TypeScript 的 Substitutability

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元