根据函数参数推断回调参数类型

时间:2020-05-07 08:58:11

标签: typescript type-inference

    type SeveralTypes = type0 | type1 | type2;
    function funTypes<T extends SeveralTypes>(info: T, callback: (obj: T extends type2 ? number : string) => void) {
        if (isType0(info)) {
            return callback("passAstring");  // TS Warn: Argument of type '"passAstring"' is not assignable to parameter of type 'T extends boolean ? number : string'

        } else if (isType1(info)) {
            return callback("passAstring"); // TS Warn: Argument of type '"passAstring"' is not assignable to parameter of type 'T extends boolean ? number : string'

        } else {
            return callback(1001); // TS Warn: Argument of type '1001' is not assignable to parameter of type 'T extends boolean ? number : string'
        }
    }

    funTypes(1, (d) => { });       // Typeof d --> string
    funTypes("str", (d) => { });   // Typeof d --> string
    funTypes(false, (d) => { });   // Typeof d --> number

当我使用此函数时,参数回调的推断类型正确。但是,TS指示分配参数时出现问题。有没有其他方法可以键入回调参数?

1 个答案:

答案 0 :(得分:1)

这里有几个问题。最主要的是缩小一个变量(在这种情况下为info)在这种情况下永远不会对另一个变量(callback)的类型产生任何影响。还有一个问题是,通常仍然包含未解析类型参数的条件类型通常很难让编译器进行推理,因此,由于T未知,并且您的函数采用依赖于T的参数,打字稿会做安全的事,不会让您numberstring

作为参数使用

解决此问题的常用方法是使用类型断言,或我的首选方法,使用通用公共签名和更宽松的实现签名(请注意,确保条件类型中的逻辑取决于您自己)是在实现中复制的,这里没有编译器的帮助

type SeveralTypes = type0 | type1 | type2;
function funTypes<T extends SeveralTypes>(info: T, callback: (obj: T extends type2 ? number : string) => void): void
function funTypes(info: SeveralTypes, callback: (obj: number | string) => void) {
  if (isType0(info)) {
    return callback("passAstring");

  } else if (isType1(info)) {
    return callback("passAstring");

  } else {
    return callback(1001); 
  }
}

funTypes(1, (d) => { });       // Typeof d --> string
funTypes("str", (d) => { });   // Typeof d --> string
funTypes(false, (d) => { });   // Typeof d --> number

Playground Link