I want to write an interpreter by TypeScript. This language has 2 primitive types and I define them as follows.
type DataType = { kind: 'number' } | {kind: 'string' }
and then I would like to define another type that also include it's 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'>;
It works well. But when I want to define a higher order type like array which can take original DataType
as parameter. I don't know how to define it. Below is what I tried:
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 seems that the value
's type depends on t
's type, but how to express their relation?
Maybe I could just expand HigherType
like 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
}
But If there are m DataType variants and n HigherType(despite Array, we may have Option, Set,......), we need to write m*n variants, and most of them have repeated part. Is there a way to only define m + n variants?