typescript - 在 TypeScript 中动态提取类型
问题描述
我正在尝试根据某些标志将一种类型动态映射到另一种类型,这可能会导致可选字段。
type Constraint = {
required: boolean,
callback: () => any,
}
type Schema = Record<string, Constraint>;
const mySchema: Schema = {
bar: {
required: true,
callback: () => 1
},
foo: {
required: false,
callback: () => true
}
}
type MapSchemaToOutput<T extends Schema> = {
[K in keyof T as T[K]['required'] extends true ? K : never]: ReturnType<T[K]['callback']>
} & {
[K in keyof T as T[K]['required'] extends false ? K : never]?: ReturnType<T[K]['callback']>
}
type Output = MapSchemaToOutput<typeof mySchema>;
最终目标是让 Output 相等:
{
bar: number,
foo?: boolean
}
我知道我可以手动进行映射,有兴趣知道这是否可以动态完成。
解决方案
您的方法按原样工作,只需进行一次更改。
问题是: Schema
注释是“丢弃类型信息”:
const mySchema: Schema = {
//...
};
有了那个注解,TS 只记住了那个mySchema
对象Record<string, Constraint>
的任何具体结构。
一种解决方法是as const
:
const mySchema = {
//...
} as const;
这保留了对象中的文字类型。但是,对 的内容不再有任何限制mySchema
,并且定义的任何错误mySchema
都必须被用法捕获,而不是在定义时捕获。
更好的解决方法是使用辅助函数来引入约束,而不直接注释类型:
function buildSchema<T extends Schema>(schema: T) { return schema; }
const mySchema = buildSchema({
//...
});
由于<T extends Schema>
约束,如果架构对象与指定类型不匹配,TS 将像以前一样引发错误。
但与注释对象的类型不同,此函数返回的此类型与传递给函数的字面量对象相比没有变化:因此不会丢失类型信息。
推荐阅读
- android - 我在修复 pub 包时遇到问题,发现这个问题
- python - 我可以使用 PHP 在 Python 应用程序中提交动态 HTML 表单吗?
- arrays - 谷歌表格:每隔一列的平均值
- html - 制作图片库只填充 l 和 right 而不是 up 和 down
- botframework - 如何让机器人在将其引导到 MS Teams 时接收附件
- javascript - 为什么 WebRTC 仅在第二次报价后才建立连接?
- ios - 防止 WKWebView 能够导航到网站上的特定页面 (Swift 5)
- python - NoneType' 对象没有属性 'system
- python - 如何在 tensorflow_datasets 加载的数据集中分别加载图像和标签
- stata - 将系列的第一次观察作为非线性回归中未观察到的参数