我有可以转换的接口--例如,它们有nameDenameFr属性.目前,我正在try 构建一个函数,该函数仅以用户语言返回name的对象.

这就是我到目前为止所知道的--它适用于已翻译的属性,但不适用于"未翻译的":

type TranslatedObject<T> = {
  [K in keyof T as K extends `${infer Name}De` ? `${Name}` : never]: T[K extends `${infer Name}De` ? K : never];
};

interface Car {
  nameDe: string,
  nameFr: string,
  price: number
}

const carWithUserLang: TranslatedObject<Car> = {
  name: 'Make Model Trim',
  price: 50000 // --> Type '{ name: string; price: number; }' is not assignable to type 'TranslatedObject<Car>'.
}

我怎么才能让它跑起来呢? Stackblitz:https://stackblitz.com/edit/typescript-h7ghdn?file=index.ts&view=editor

推荐答案

我的假设是,您希望TranslatedObject<T>go 掉键名称"De""Fr"的末尾(如果它们存在的话),否则就不管它们了.如果是这样,则这纯粹是一个key remapping操作,不会更改属性值类型.就像这样:

type TranslatedObject<T> = {
  [K in keyof T as K extends `${infer Name}${"De" | "Fr"}` ? Name : K]: T[K];
};

它在template literal type中使用conditional type inference来go 掉任何"De""Fr"后缀.判断K extends `${infer Name}${"De" | "Fr"}`试图将K与以某个任意字符串开始并以"De" | "Fr"结束的内容进行匹配;如果成功,则推断Name是该任意初始字符串.因此,如果解析成功,则结果键类型的计算结果为Name,如果解析失败,则计算结果为K.

这就产生了您所期望的类型:

interface Car {
  nameDe: string,
  nameFr: string,
  price: number
}

type TranslatedCar = TranslatedObject<Car>;
/* type TranslatedCar = {
    name: string;
    price: number;
} */

请注意,有一些有趣的边缘情况,例如,如果两个关键点具有不同的值类型会发生什么情况:

type Weird = TranslatedObject<{
  oopsDe: string;
  oopsFr: number;
  other: boolean;
}>

/* type Weird = {
    oops: string | number; // <-- becomes union
    other: boolean;
} /

这可能是人们所期待的,也可能不是.重点是,人们应该始终针对自己的用例进行彻底的测试.

Playground link to code

Typescript相关问答推荐

处理API响应中的日期对象

将props传递给子组件并有条件地呈现它''

如何根据模板类型实现不同的模板函数行为?

react 路由6操作未订阅从react 挂钩表单提交+也不使用RTK查询Mutations

创建一个根据布尔参数返回类型的异步函数

如何使用Zod使一个基于其他字段值的字段为必填字段?

在实现自定义主题后,Angular 不会更新视图

TypeScrip泛型类未提供预期的类型错误

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

如何将对象数组中的键映射到另一种对象类型的键?

如何在脚本中输入具有不同数量的泛型类型变量的函数?

在TypeScript中扩展重载方法时出现问题

类型与泛型抽象类中的类型不可比较

抽象类对派生类强制不同的构造函数签名

在TypeScript中,如何通过一系列过滤器缩小类型?

我如何键入它,以便具有字符串或数字构造函数的数组可以作为字符串或数字键入s或n

将对象数组传递给 Typescript 中的导入函数

有没有办法从不同长度的元组的联合中提取带有类型的最后一个元素?

将 Angular 从 14 升级到 16 后出现环境变量注入问题

组件的第二个实例使用 svelte 中第一个实例上设置的函数