Reputation: 419
interface Num {
type: 'number',
default: number
}
interface Bool {
type: 'boolean'
default: boolean
}
interface Str {
type: 'string',
default: string
}
type UnionType = Num | Bool | Str
interface IOption<T extends string, CFG extends Record<T, UnionType>> {
configs: CFG,
// I don't know how to write this line to make each key matches its own value type
// i.e. `{key1: Num, key2: Bool, key3: Str}`
defaultOverwrite?: Partial<{ [key in T]: CFG[key]['default'] }>
}
declare function checker<T extends string, CFG extends Record<T, UnionType>>(option: IOption<T, CFG>): void
checker({
configs: {
// key1 errors as expected, which default should be a number
key1: { type: 'number', default: '' },
key2: { type: 'boolean', default: true },
key3: { type: 'string', default: 'string' },
},
defaultOverwrite: {
// the value of `key1` should match the type of configs.key1.default, which is a number.
// expected error here, but I don't know how
key1: '3'
}
})
See the above case.
I want to check the configs
type which value should matches UnionType
,
also, I want to check defaultOverwrite
type, which should has partial key of configs
and the corresponding value type as the configs
declared.
But I don't know how, anyone can help me?
I rethought about my question, the real problem is we need to make a union value record to become exact type when assigned value, like
type A = {[key: string]: string | number}
// when declared
const a: A = {
key1: 1,
key2: 'str'
}
I want a
to match type A
but also generate a exact type which is
interface ExactA{
key1: number,
key2: string
}
Upvotes: 3
Views: 337
Reputation: 10881
You can't expect more then ONE error in a generic
The error in defaultOverwrite
will appear as soon as you fix the error in configs
checker({
configs: {
key1: { type: 'number', default: 1 }, // error fixed
key2: { type: 'boolean', default: true },
key3: { type: 'string', default: 'string' },
},
defaultOverwrite: {
key1: '1' // a new error has spawned
// (property) key1?: number | undefined
//Type 'string' is not assignable to type 'number'.(2322)
}
})
Upvotes: 1