假设我有以下定义:
export enum Category {
car = 'car',
truck = 'truck',
}
export interface IProperty {
propertyName: string,
propertyLabel: string,
propertyType: 'string' | 'number',
}
export interface CategoryDefinition {
category: Category,
label: string,
properties: IProperty[]
}
然后有这样的定义:
export class Definitions {
public static get car(): CategoryDefinition {
return {
category: Category.car,
label: "Car",
properties: [
{
propertyName: 'weight',
propertyLabel: 'Weight',
propertyType: 'number'
},
{
propertyName: 'color',
propertyLabel: 'Color',
propertyType: 'string'
}
],
};
}
public static get truck(): CategoryDefinition {
return {
category: Category.truck,
label: "Truck",
properties: [
{
propertyName: 'payload',
propertyLabel: 'Payload',
propertyType: 'number'
},
{
propertyName: 'axles',
propertyLabel: 'Axles',
propertyType: 'number'
}
],
};
}
}
现在,我想从这个定义中生成接口,结果应该是:
export interface Car {
weight: number,
color: string
}
export interface Truck{
payload: number,
axles: number
}
理想的做法是:
export interface Car = createInterface('Car', Definitions.car.properties);
export interface Truck = createInterface('Truck', Definitions.truck.properties);
原因是我必须处理其中的30 - 40个定义。我当然可以自己定义它们的接口(API响应),但之后我必须重新定义它们的属性以用于UI显示,这很容易出错。这样我只需要定义它们的属性,就可以生成它们相应的接口。
我发现an answer可能暗示了正确的方向,但是我觉得它不太一样,我不能让它工作。
如果有帮助,定义将是固定的(即不动态更改/更新)。
任何帮助都将不胜感激。
2条答案
按热度按时间4nkexdtk1#
您可能应该将定义类型设置为只读(因为您不需要在运行时更改这些类型):
另一个需要做的更改是使用
as const satisfies CategoryDefinition
,而不是将返回类型注解为CategoryDefinition
,这样可以在确保返回类型为CategoryDefinition
的同时“保留”值。然后我们需要定义一个类型,将属性类型Map到它们的实际类型:
最后,我们可以Map定义属性并为每个字段检索正确的类型:
Playground
你的Definitions类真的需要是一个类吗?它可以是:
这样更容易阅读和维护。
ipakzgxi2#
您必须为此创建自定义类型,这将需要一些工作(通常建议使用Zod之类的第三方库来为您也希望在TypeScript中访问的类型定义“模式”。但是,如果您不想使用第三方库,我将看看是否可以找到一些适合您的用例的类型。
这是个工作场所
有一些事情你需要调整你的定义(vera在另一个答案中解释了),但这里是我想出的“神奇”类型:
它所做的是循环遍历所有属性,然后使用
TypeMap
类型(“string”-〉string
,“number”到number
)将字符串化类型“Map”到实际的TypeScript类型(这个想法归功于vera)问题是,随着类型变得越来越复杂,您需要自己维护这些值的Map,这就是为什么存在像zod这样的第三方库的原因;来为您处理这些值-〉类型Map(我推荐使用)。