Home > Blockchain >  TypeScript arguments of union of functions are transformed to "never"
TypeScript arguments of union of functions are transformed to "never"

Time:11-21

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)
}
  • Related