I have few different interfaces. Each of them contains property called type
.
interface Type1 { type: 'key1', name: string }
interface Type2 { type: 'key2', description: string, name: string }
interface Type3 { type: 'key3', cost: number }
mapping interface
interface TypeMap {
key1: Type1,
key2: Type2,
key3: Type3
}
And union type
type TypeElement = Type1 | Type2 | Type3
Map object, that uses record of each type separately. Each record in the function has its own type. Just like the mapping interface
const allTypes: { [key in keyof TypeMap]: (record: TypeMap[key]) => void } = {
key1: (record) => {},
key2: (record) => {},
key3: (record) => {},
}
When I pass a variable of type TypeElement
into a callback from allTypes
, it gives me an error
const func = (record: TypeElement) => {
const cb = allTypes[record.type]
return cb(record)
}
Here cb
type is ((record: Type1) => void) | ((record: Type2) => void) | ((record: Type3) => void)
But when I try to call it cb(record)
it tells that cb
type is (record: never) => void
The error is:
Argument of type 'TypeElement' is not assignable to parameter of type 'never'. The intersection 'Type1 & Type2 & Type3' was reduced to 'never' because property 'type' has conflicting types in some constituents. Type 'Type1' is not assignable to type 'never'.
Why I get that error? What is wrong with that? How I can pass record to cb
without giving me an error? record as never
, as any
are not the solutions I am looking for!
CodePudding user response:
interface Type1 { type: 'key1', name: string }
interface Type2 { type: 'key2', description: string, name: string }
interface Type3 { type: 'key3', cost: number }
interface TypeMap {
key1: Type1,
key2: Type2,
key3: Type3
}
type TypeElement = Type1 | Type2 | Type3
const allTypes: { [key in keyof TypeMap]: (record: TypeMap[key]) => void } = {
key1: (record) => {},
key2: (record) => {},
key3: (record) => {},
}
const func = <K extends keyof TypeMap>(record: TypeMap[K]) => {
const cb = allTypes[record.type as K]
return cb(record)
}