我具有预定义的字符串数组STRINGS_ARR.

我正在try 使用该数组中的字符串创建对象STRINGS_OBJ.

对象的每个键应该是通过从输入字符串中移除下划线字符来动态生成的,值应该是输入字符串本身.

例如:如果输入的字符串是‘Some_Test_Name’,则key应该是‘SomeTestName`,key的值应该是’Some_Test_Name‘.

我能够编写代码来满足需求,并使用所需的键/值对生成这样的对象.

但是,我不能编写类型/定义对象的 struct ,以便类型脚本能够正确地推断给定键的值.

这就是我到目前为止所拥有的,而TypeScrip无法推断出Value的类型,这是正确的,因为我试图从InputString中提取的Key已经被修改,不再匹配.

type InputStringMap = {
  [Key in KeyName<InputString>]: Extract<InputString, Key>
};
type Key = keyof InputStringMap;
type Value = InputStringMap[Key];
//   ^? type Value = never

这种对象的正确类型/定义应该是什么?

type InputString = 'Test_String_1' | 'Test_String_2';
const STRINGS_ARR: InputString[] = ['Test_String_1', 'Test_String_2'];

type KeyName<S extends string> = string extends S ? 'Error' : S extends `${infer A}_${infer B}` ? KeyName<`${A}${B}`> : S;

type InputStringMap = {
  [Key in KeyName<InputString>]: Extract<InputString, Key>
};
type Key = keyof InputStringMap;
type Value = InputStringMap[Key];
//   ^? type Value = never

const keyValuePairs = STRINGS_ARR.map<[Key, Value]>((str) => [str.replace(/_/g, '') as Key, str as Value]);
const STRINGS_OBJ = Object.fromEntries(keyValuePairs) as InputStringMap;

Playground

推荐答案

最简单的方法是使用key remapping via as:

type InputStringMap = {
  [K in InputString as KeyName<K>]: K
};

它产生了

/* type InputStringMap = {
    TestString1: "Test_String_1";
    TestString2: "Test_String_2";
} */

如你所愿.

Playground link to code

Typescript相关问答推荐

TypScript ' NoInfer '类型未按预期工作

Angular 信号:当输入信号改变值时,S触发取数的正确方式是什么?

带switch 的函数的返回类型的类型缩小

尽管对象的类型已声明,但未解析的变量<;变量

剧作家元素发现,但继续显示为隐藏

使用条件类型的类型保护

为什么我在这个重载函数中需要`as any`?

TypeScrip错误:为循环中的对象属性赋值

创建Angular 为17的动态形状时出错

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

TypeScrip:使用Cypress测试包含插槽的Vue3组件

如何键入对象转换器

两个名称不同的相同打字界面-如何使其干燥/避免重复?

我可以将一个类型数组映射到TypeScrip中的另一个类型数组吗?

如何使用useSearchParams保持状态

如何实现允许扩展泛型函数参数的类型

如何使用 runInInjectionContext 中的参数测试功能性路由防护

使用 fp-ts 时如何使用 TypeScript 序列化任务执行?

在Nestjs中,向模块提供抽象类无法正常工作

使用泛型时记录无法建立索引