I've a type FieldType
which is an enum and FieldTypeToTSType
which gets a FieldType
as a parameter and converts it to the typescript type.
type FieldType = "string" | "int";
type FieldTypeToTSType<T extends FieldType> =
T extends "string" ? string
: T extends "int" ? number
: never;
but the problem is using it directly works:
FieldTypeToTSType<"string"> // string
FieldTypeToTSType<"int"> // number
but when I'm using FieldType
it always defines it as string
const a: FieldType = "int";
type K = FieldTypeToTSType<typeof a>; // string but it should be number
the context that I'm using it:
type FieldType = "string" | "int";
type FieldDefinition = {
type: FieldType;
};
type EntityDefinition<T> = {
[K in keyof T]: FieldDefinition;
};
const makeEntity = <T>(et: { [K in keyof T]: FieldDefinition }) => et;
type FieldTypeToTSType<T extends FieldType> = T extends "string"
? string
: T extends "int"
? number
: never;
type EntityRefrence<T extends EntityDefinition<T>, R extends keyof T = keyof T> = {
[key in R]: FieldTypeToTSType<T[R]["type"]>;
};
const Vacation = makeEntity({
days: {
type: "int",
},
name: {
type: "string"
}
});
type VacationRef = EntityRefrence<typeof Vacation>;
VacationRef's type should be
type VacationRef = {
days: number;
name: string;
}
but it is:
type VacationRef = {
days: string | number;
name: string | number;
}
It doesn't work because FieldType
of source entity is widened in makeEntity
and EntityRefrence
. To fix this in EntityRefrence
- use specific key instead of union of all possible keys:
type EntityRefrence<T extends EntityDefinition<T>> = {
[key in keyof T]: FieldTypeToTSType<T[key]["type"]>;
};
In makeEntity
- passed parameter should have generic type, so its type properly inferred and not widened:
const makeEntity = <T extends { [K in keyof T]: FieldDefinition }>(et: T) => et;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.