其值与其键匹配的对象的TypeScript类型

时间:2020-06-22 21:05:34

标签: typescript typescript-generics conditional-types mapped-types

是否可以为对象定义TypeScript类型,而键值本身就是文字键名?例如:

declare const $: SpecialGenericType

$.prop // typed as the literal value "prop"

const values = [
  $.a,
  $.b,
  $.c
] as const

// values has the type (and value) ["a", "b", "c"]

可以使用代理来实现$对象,但是我不确定如何实现SpecialGenericType。该类型将需要允许任何字符串作为键,但是值将需要键入为其键名的字符串文字(因此Record<string, string>在这种情况下不起作用)。例如,上面的values的元组类型为["a", "b", "c"]

2 个答案:

答案 0 :(得分:2)

您正在寻找的内容目前在TypeScript中无法实现。如果您具有一些字符串文字键的有限联合,则适用,但不适用于所有stringmicrosoft/TypeScript#22509提出了一个公开的建议,要求提供确切的信息(在描述中称为Thing而不是SpecialGenericType),但没有任何动静。首席语言设计师said

这实际上是一个请求,要求添加对ECMAScript代理对象的编译器支持,即,对属性访问操作与getset代理方法之间的关系的编译器知识。根本不可能使用我们当前的类型系统功能对其进行建模(因为没有任何内容允许您捕获与属性访问中的属性名称相对应的文字类型)。

您可能想要解决该问题并给它一个?或描述为什么您认为您的用例引人注目,但是我怀疑它会很快实现。哦,好吧,至少对这个问题有一个明确的答案,即使它不是。祝你好运!

答案 1 :(得分:0)

如果我理解正确,那就是你想要的:

type SpecialGenericType<T extends object> = {
  [K in keyof T]: K
};

function proxify<T extends object>(source: T) {
  const proxy = new Proxy(source, {
    get: (_, property) => {
      return property
    }
  });

  return proxy as SpecialGenericType<T>;
}

const $ = proxify({
  prop: {},
  a: 'some',
  b: 'random',
  c: 'values',
} as const)

$.prop // typed as the literal value "prop"

const values = [
  $.a,
  $.b,
  $.c
] as const

// values has the type (and value) ["a", "b", "c"];