Typescript - 根据提供的对象键检测值类型

标签 typescript type-inference

鉴于我有这样的类型:

type Foo = {
  foo: number;
  bar: string;
  baz: boolean;
}

我想要一个类型 Buzz ,它可以检测键的值类型,即

const abc: Buzz<Foo> = {
  key: 'foo',
  formatter: (detectMe) => {} //I want TS to infer this to be 'number'
};

给定键“foo”,格式化程序中的参数应该被推断为number。我试过这个:

interface ColumnDescription<T> {
  label: string;
  key: keyof T;
  formatter?: (datum: T[keyof T]) => void;
}

然而,这会导致参数被推断为 number |字符串| bool 值.

也尝试过这个:

interface ColumnDescription<T, K extends keyof T> {
  label: string;
  key: K;
  formatter?: (datum: T[K]) => void;
}

这种方法可行,但我总是需要在第二个类型参数中指定键,而不是自动发生。即:

const abc: Buzz<Foo, 'foo'> = { //I don't want to specify the key
  key: 'foo',
  formatter: (detectMe) => {} //This is inferred correctly
};

最佳答案

就像我的评论一样,我建议

type Buzz<T> = {
  [K in keyof T]-?: { key: K; formatter: (d: T[K]) => void }
}[keyof T];

这与您对 Buzz<T, K extends keyof T> 所做的类似,而不是制作 Buzz需要 K需要说明的是,我使用了 mapped type {[K in keyof T]: ...}它会自动迭代 keyof T 中的键并使用相同的键创建一个新对象,但其属性值是您要查找的类型。这意味着获得所需的 Buzz<T>我们需要look up属性值,通过使用 [keyof T] 对其进行索引。这使得Buzz<T>类型的联合,其中联合的每个组成部分对应于您的 Buzz<T, K extends keyof T>对于特定键K

让我们确保它有效:

const abc: Buzz<Foo> = {
  key: "foo",
  formatter: detectMe => {} // inferred as number, as desired
};

看起来不错,让我们检查一下 abc 的类型使用智能感知:

const abc: {
    key: "foo";
    formatter: (d: number) => void;
} | {
    key: "bar";
    formatter: (d: string) => void;
} | {
    key: "baz";
    formatter: (d: boolean) => void;
}

看起来也不错。

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

Link to code

关于Typescript - 根据提供的对象键检测值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56828431/

相关文章:

scala - Scala 中的 PartialFunction 类型推断

c# - 从 MSBuild 3.5 而不是 Visual Studio 编译的类型推断失败 (CS0246)

Java泛型方法: inconsistency when inferring upper bound on return type from argument type

typescript - Eslint 规则 @typescript-eslint/naming-convention 与 @typescript-eslint/no-unused-vars 冲突

typescript - 如何使用 TypeScript Playground 导入库

javascript - 如何在Angular4中使用用户页面注册时更改主页的内容

JavaScript 错误 : Cannot read property 'includes' of undefined

typescript - TS - 如何对泛型类型内的类型值执行字符串函数

lambda - Java 8 类型推断错误,将 lambda 表达式分配给 Object 类型的变量

Clojure 在类型推断方面的不足