Can TypeScript infer the type based on the content of an object?
For example:
type MyKeyList =
| "A"
| "B"
| "C"
;
type MyType<T extends MyKeyList> = {
type: T,
value: T extends "A"
? 1
: T extends "B" ? 2 : 3
};
// Is there a way to perform this kind of check?
// Or is it simply not possible.
const MyObject: MyType = {
type: "B"
}
Is there any method to achieve dynamic types like this?
Or is it just a limitation of TypeScript.
edit
The example above is simplified. Here is a more complex case I'm working with. The following type may not be practical, as it's just for demonstration purposes.
type Type1 =
| "A" | "B" | "C" | ... | "Z";
type Type2 =
| "AA" | "BB" | "CC" | ... | "ZZ";
type Type3 = true | false | "AAA" | "BBB" | "CCC";
type Field1Type<
T extends Type1,
S extends ("AA" | "BB" | "CC" | undefined) = undefined
> = (value: number) => `${T}-${S}-${number}`;
type Field2Type<T extends ("X" | "Y" | "Z")> =
(value: boolean) => `${boolean}-${T}`;
type Field3Type<
T extends Exclude<Type1, "X" | "Y" | "Z">,
S extends ("AA" | "BB" | "CC")
> = (value: string) => `${T}-${string}-${S}`
type MyType<
T extends Type1,
S extends Type2,
U extends Type3
> = {
t: T,
s: S,
u: U,
field1: U extends true
? Field1Type<T>
: S extends ("AA" | "BB" | "CC")
? Field1Type<T, S>
: never,
field2: T extends ("X" | "Y" | "Z")
? Field2Type<T>
: never,
field3: U extends (true | false)
? never
: T extends ("X" | "Y" | "Z")
? never
: S extends ("AA" | "BB" | "CC")
? Field3Type<Exclude<T, "X" | "Y" | "Z">, S>
: never,
};
const tmp: MyType = {
t: "A",
s: "AA",
u: true,
};