打字稿无法检测到该属性是一个函数

时间:2018-09-21 08:34:36

标签: typescript generics

我正在使用intl-ts库。以下函数无法编译,因为它抱怨lang[result]未知可执行文件:

function convertResult<
  T extends Messages &
    { [P in K]: (fieldName: string, p1: P1, p2: P2, p3: P3, p4: P4) => string },
  K extends keyof T,
  P1 = any,
  P2 = any,
  P3 = any,
  P4 = any
>(
  result: K | null,
  params: [P1, P2, P3, P4],
  lang?: Intl<T>,
  fieldName?: string
): boolean | string | null {
  if (result === null) {
    return lang ? null : true
  } else {
    if (lang) {
      return lang[result](fieldName, ...params)
    } else {
      return false
    }
  }
}

我相信Kresult的类型)的定义足以使编译器知道lang[result]确实是采用适当参数的方法。

所以,我想知道问题是否存在:

  • 这段代码中我错过的东西。
  • 我在intl-ts中错过的东西(我是此软件包的维护者)。
  • 或者对于Typescript来说太复杂的东西,也许我应该为此打开一个问题。

提供了一个简单的示例here

1 个答案:

答案 0 :(得分:1)

问题是由于与Messages相交引起的。因此,Typescript无法正确推断索引访问的corect类型。

在这种情况下,我将删除交点。不要以为它起着主要作用,只是重申T必须包含函数或字符串,用于约束T的映射类型要严格得多,因此如果对象符合约束的T符合Messgaes

function convertResult<
    T extends { [P in K]: (fieldName: string, p1: P1, p2: P2, p3: P3, p4: P4) => string },
    K extends keyof T,
    P1 = any,
    P2 = any,
    P3 = any,
    P4 = any
    >(
        result: K | null,
        params: [P1, P2, P3, P4],
        lang?: T,
        fieldName?: string
    ): boolean | string | null {
    if (result === null) {
        return lang ? null : true
    } else {
        if (lang) {
            return lang[result](fieldName, ...params)
        } else {
            return false
        }
    }
}