Issue
Let’s say I’m trying to create a Variable type that takes a type key which has a type of string: is there a way to access the value from the key called type and use that as the type for another key in that type declaration? (Without using Generic Types)
For example,
type Variable = {
name: string;
required: boolean;
type: string;
defaultValue: Variable["type"];
}
const newWorkingVar: Variable = {
name: "count",
required: true,
type: "number",
defaultValue: 22 // This should work
}
const newErrorVar: Variable = {
name: "count",
required: true,
type: "number",
defaultValue: "test" // This should error
}
Solution
This answer is similar to @LindaPaiste’s, with the minor change that the mapping from names to types is kept in a separate type, which is then manipulated to produce Variable
. For example, your mapping could look like this:
type TypeMapping = {
number: number;
string: string;
boolean: boolean
// add more here as needed
}
And then Variable
could be
type Variable = { [K in keyof TypeMapping]: {
name: string;
required: boolean;
type: K;
defaultValue: TypeMapping[K];
} }[keyof TypeMapping]
This works by taking each key K
from TypeMapping
and transforming the property type from TypeMapping[K]
to the subtype of Variable
for that K
(where type
is the key and defaultValue
is the property type). The resulting mapped type is not exactly what we want because it still has the same keys as TypeMapping
. We get the union of its properties by indexing into it.
Result:
/* type Variable = {
name: string;
required: boolean;
type: "string";
defaultValue: string;
} | {
name: string;
required: boolean;
type: "number";
defaultValue: number;
} | {
name: string;
required: boolean;
type: "boolean";
defaultValue: boolean;
} */
And now you get the behavior you’re looking for:
const newWorkingVar: Variable = {
name: "count",
required: true,
type: "number",
defaultValue: 22 // okay
}
const newErrorVar: Variable = {
name: "count",
required: true,
type: "number",
defaultValue: "test" // error!
}