TypeScript数组(元组)使用keyof typeof解构位置的特定类型

时间:2019-10-01 15:45:13

标签: typescript

我有一个要分割的字符串,分割后的字符串的结果非常具体,我要输入:

const [validator, argument]: [keyof typeof validators, string] = validation.split(':');

我知道validator将是keyof typeof validators,但我在TS中遇到错误:

TS2739: Type 'string[]' is missing the following properties from type '[string | number, string]': 0, 1

TypeScript不喜欢它的原因是什么?我已经四处搜寻,找不到这个问题的答案。

2 个答案:

答案 0 :(得分:2)

.split返回一个Array<string>,而不是一个元组。如果您确实确定自己在做什么,则必须使用as any并进行显式强制转换,或者编写一个函数来检查输出。

使用any

const [validator, argument]: [keyof typeof validators, string] = validation.split(':') as any;

更安全,但是您将不得不处理错误返回的可能性:

const isKeyOf = <T extends object>(k: string | keyof T, obj: T): k is (keyof T) => obj.hasOwnProperty(k)

const safer = (from: string): [keyof typeof validators, string] => {
  const [first, second] = string.split(":)

  if (first && second && isKeyOf(first, validators)) {
    return [first, second]
  }

  return Error("Not a valid input.")
}

答案 1 :(得分:1)

请注意,@chautelly's answer是正确的,唯一可能的问题是对any的声明比实现此功能所需的宽松得多,我建议直接向元组声明。如果该答案得到更新以考虑到这一点,我很乐意将其删除。


TypeScript不知道split()将返回一对(两个元组)。它只知道它将返回一个string[]。因此,错误是说string[]split()返回的内容)可能在一对的01键处没有属性,因此这是不安全的将其分配给您的配对类型。

在您知道自己在做的事是安全的情况下(这意味着您已经以某种方式将validation约束为其中仅包含一个冒号的字符串,其中前缀是{{ 1}}),则可以使用type assertion

validation

类型断言会使您不安全地缩小表达式的类型,这意味着您可以告诉编译器,表达式的类型比它可以验证的更具体。编译器知道const [validator, argument] = validation.split(":") as [ keyof typeof validators, string ]; // okay now 返回一个validation.split(),并且您断言它特别是string[]的子类型[keyof typeof validators, string]

请注意,类型断言允许您对编译器撒谎,因此,您有责任不这样做。如果在运行时发现string[]的值与您期望的值不同,那么将发生奇怪的事情,并且编译器可能无法帮助您避免这些情况。如果您希望避免这些问题,那么您可能需要使用某种type guards来实际验证validation是您期望的配对类型。如果您已经在某处进行了此测试,则可能值得以编译器认为是类型保护的形式重写此测试。

好的,希望能有所帮助;祝你好运!