打字稿:根据另一个 属性 值强制执行 属性 类型,该值是泛型的键
Typescript: Enforcing property type based on another property value which is a key of a generic
给定以下类型:
export type MyType = {
a: boolean;
b: number;
}
我要创建类型:
export type Mapper<T> = {
key: keyof T;
func: (value: string) => T[key];
}
这样我就可以拥有:
const mapToMyTypePropertyA: Mapper<MyType> = {
key: "a",
func: v => !!v // enforce output type to be the type of MyType["a"], which is boolean
};
const mapToMyTypePropertyA: Mapper<MyType> = {
key: "b",
func: v => v.length // enforce output type to be the type of MyType["b"], which is number
};
即我想强制 func
的 return 类型(这是一个函数)成为由 key
(这是一个通用类型的键)。
这可能吗?
到目前为止我只能做到这一点:
export type Mapper<T, K extends keyof T> = {
key: K;
func: (value: string) => T[K];
}
const mapToMyTypePropertyA: Mapper<MyType, "a"> = {
key: "a",
func: v => !!v // I get the enforcement here
}
但这需要在泛型和 属性 key
.
中重复密钥两次
您可以使用另一种类型来“生成”可能的对象:
type GenerateCombos<T> = {
[K in keyof T]: {
key: K;
func: (value: string) => T[K];
};
}[keyof T];
这将为我们提供一个允许对象的联合。例如,GenerateCombos<{ foo: string }>
只会给我们:
{ key: "foo"; func: (value: string) => string }
而 GenerateCombos<MyType>
给了我们很好的类型:
{
key: "a";
func: (value: string) => boolean;
} | {
key: "b";
func: (value: string) => number;
}
要使用它,可以先给它起个别名:
type Mapper = GenerateCombos<MyType>;
然后注释变量的类型:
const mapToMyTypeProperty1: Mapper = {
key: "a",
func: v => !!v // enforce output type to be the type of MyType["a"], which is boolean
};
const mapToMyTypeProperty2: Mapper = {
key: "b",
func: v => v.length // enforce output type to be the type of MyType["b"], which is number
};
如果操作不当也会报错:
const mapToMyTypeProperty3: Mapper = {
key: "a",
func: v => v // ! error
};
const mapToMyTypeProperty4: Mapper = {
key: "b",
func: v => !!v // ! error
};
试试这个 here。
给定以下类型:
export type MyType = {
a: boolean;
b: number;
}
我要创建类型:
export type Mapper<T> = {
key: keyof T;
func: (value: string) => T[key];
}
这样我就可以拥有:
const mapToMyTypePropertyA: Mapper<MyType> = {
key: "a",
func: v => !!v // enforce output type to be the type of MyType["a"], which is boolean
};
const mapToMyTypePropertyA: Mapper<MyType> = {
key: "b",
func: v => v.length // enforce output type to be the type of MyType["b"], which is number
};
即我想强制 func
的 return 类型(这是一个函数)成为由 key
(这是一个通用类型的键)。
这可能吗?
到目前为止我只能做到这一点:
export type Mapper<T, K extends keyof T> = {
key: K;
func: (value: string) => T[K];
}
const mapToMyTypePropertyA: Mapper<MyType, "a"> = {
key: "a",
func: v => !!v // I get the enforcement here
}
但这需要在泛型和 属性 key
.
您可以使用另一种类型来“生成”可能的对象:
type GenerateCombos<T> = {
[K in keyof T]: {
key: K;
func: (value: string) => T[K];
};
}[keyof T];
这将为我们提供一个允许对象的联合。例如,GenerateCombos<{ foo: string }>
只会给我们:
{ key: "foo"; func: (value: string) => string }
而 GenerateCombos<MyType>
给了我们很好的类型:
{
key: "a";
func: (value: string) => boolean;
} | {
key: "b";
func: (value: string) => number;
}
要使用它,可以先给它起个别名:
type Mapper = GenerateCombos<MyType>;
然后注释变量的类型:
const mapToMyTypeProperty1: Mapper = {
key: "a",
func: v => !!v // enforce output type to be the type of MyType["a"], which is boolean
};
const mapToMyTypeProperty2: Mapper = {
key: "b",
func: v => v.length // enforce output type to be the type of MyType["b"], which is number
};
如果操作不当也会报错:
const mapToMyTypeProperty3: Mapper = {
key: "a",
func: v => v // ! error
};
const mapToMyTypeProperty4: Mapper = {
key: "b",
func: v => !!v // ! error
};
试试这个 here。