我有一个枚举来描述“字段”,以及每个字段到类型的映射:
enum Field {
Id,
Position,
Name,
Enabled,
}
interface FieldTypes extends Record<Field, any> {
[Field.Id]: number;
[Field.Position]: number;
[Field.Name]: string;
[Field.Enabled]: boolean;
}
Run Code Online (Sandbox Code Playgroud)
我编写了一个函数来从某些字段中提取给定的字段data(我在这里将其定义为unknown类型,因为它对于这个问题并不重要):
declare function getField<F extends Field>(
data: unknown,
field: F
): FieldTypes[F];
const position: number = getField({}, Field.Position);
const name: string = getField({}, Field.Name);
Run Code Online (Sandbox Code Playgroud)
这编译没有错误。getField确实返回一个numberforposition和一个stringfor name。
现在我想编写一个按顺序getFields提取多个字段的函数data,但我很难定义它。我期望它的工作方式如下:
const fields: [boolean, number, number] = getFields({}, [
Field.Enabled,
Field.Id,
Field.Position,
]);
Run Code Online (Sandbox Code Playgroud)
那么如何定义这个函数呢?这是我尝试过的,但它没有返回正确的类型:
declare function getFields<F extends Field>(
data: unknown,
fields: F[]
): FieldTypes[F][];
Run Code Online (Sandbox Code Playgroud)
这应该适合你:
enum Field {
Id,
Position,
Name,
Enabled,
}
interface FieldTypes extends Record<Field, any> {
[Field.Id]: number;
[Field.Position]: number;
[Field.Name]: string;
[Field.Enabled]: boolean;
}
Run Code Online (Sandbox Code Playgroud)
首先,我们创建另一个type,它接受一个元组Field并返回一个具有相应类型的元组。
type MultipleFieldTypes<T extends readonly Field[]> = {
[K in keyof T]: T[K] extends keyof FieldTypes ? FieldTypes[T[K]] : never
}
Run Code Online (Sandbox Code Playgroud)
然后我们修改函数getFields以接受元组Field作为泛型类型F。作为返回类型,我们传递F给MultipleFieldTypes.
declare function getFields<F extends Field[]>(
data: unknown,
fields: [...F]
): MultipleFieldTypes<F>;
Run Code Online (Sandbox Code Playgroud)
现在我们有了正确的返回类型:
const fields: [boolean, number, number] = getFields({}, [
Field.Enabled,
Field.Id,
Field.Position,
]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |