我有这样的代码设置。
我希望返回的数据具有一个动态类型约束。
type Schema = ('id' | 'name' | 'description' | 'content' | 'createdAt')[];
type Obj = {
id: number;
name: string;
description: string;
content: string;
createdAt: Date;
}
function getBySchema(schema: Schema) {
const result = /* Get the object of the specified field from somewhere according to the schema */
return result;
}
const picked = getBySchema(["id", "name"]);
// Expect it to pass.
picked.name
// Expect it not to pass.
picked.createdAt
我在函数的参数类型中指定Schema以获得输入提示符。
如何根据模式的实际值动态计算结果的类型?
我尝试过以下几种方法,但是它似乎是基于模式中的所有类型来做出判断的。
type PickBySchema<T extends Record<string, unknown>, S extends Schema> = S extends (infer I)[] ? I extends string ? {
[K in I]: T[K]
} : never : never;
发布于 2022-05-28 04:50:12
您可以使用(infer U)[] ? U : never
推断传递的字符串元组,并将它们映射为结果对象键,如下所示:
function getBySchema<T extends Schema>(schema: T): {
[key in (T extends (infer U)[] ? U : never)]: Obj[key]} {
解释:
T extends Schema
确保schema: T
的传入参数为Schema
类型。Schema
字符串的一个联合。为此,我们使用key in
约定启动接口,该约定用于迭代一个联合类型来创建属性键。联合类型是通过扩展泛型T
变量并通过使用(infer U)[] ? U : never
语法推断其条目为新的联合类型来创建的,该语法获得对T有效的最小的联合类型(即传入的内容)。: never
表达式用于指示,如果不能推断合并,则key
将不是有效值,也不能使用。Obj[key]
,这将确保属性值具有与键相应的正确类型。操场链接。
对代码基的进一步改进:
您不必手动键入Obj
类型中的键并将它们分配给Schema
类型。您可以通过以下方法实现自动化:
type Schema = (keyof Obj)[];
操场链接。
https://stackoverflow.com/questions/72415302
复制