I am interested in creating an interpreter using TypeScript. This language has 2 primitive types, which I have defined as follows:
type DataType = { kind: 'number' } | {kind: 'string' }
Next, I would like to define another type that also includes its instance.
type _DataType<T extends 'type' | 'typedValue'> = {
kind: 'number',
value: T extends 'type' ? undefined : number,
} | {
kind: 'string'
value: T extends 'type' ? undefined : string,
}
type DataType = _DataType<'type'>;
type TypedValue = _DataType<'typedValue'>;
Everything seems to be working well so far. However, I am facing a challenge when trying to define a higher-order type like an array that can take the original DataType
as a parameter. Here is what I have attempted:
type _HigherType<T extends 'type' | 'typedValue'> = {
kind: 'Array',
t: DataType,
value: Array<?????>
} | {
kind: 'Single',
t: DataType,
value: ?????
}
type HigherType = _HigherType<'type'>;
type HigherTypedValue = _HigherType<'typedValue'>;
It appears that the type of value
depends on the type of t
, but how can I express their relationship?
I am considering expanding HigherType
as shown below:
type _HigherType<T extends 'type' | 'typedValue'> = {
kind: 'Array',
t: { kind: 'number },
value: T extends 'type' ? undefined : Array<number>
} | {
kind: 'Array',
t: { kind: 'string' },
value: T extends 'type' ? undefined : Array<string>
} | {
kind: 'single',
t: { kind: 'number' },
value: T extends 'type' ? undefined : number
} | {
kind: 'single',
t: { kind: 'string' },
value: T extends 'type' ? undefined : string
}
However, if there are m variants of DataType and n variants of HigherType (besides Array, e.g., Option, Set, etc.), we would need to write m*n variants, most of which have repeated parts. Is there a way to define only m + n variants?