guang y
guang y

Reputation: 31

TypeScript get generic property

My code is Here

The type1 I can the result I want, but I got a type check error, even I suppress with @ts-ignore, it still popup errors. The type2 is legal, but doesn't work.

I thought may in T[Field['name']], the code 'Field['name']' isn't consider as a value?

interface Req{
  stringField:string,
  dateField:string,
  numberField:number
}

type Field<T>={
  name: keyof T;
  // get T['name'],base on T['name']'s type,return values  

  // @ts-ignore 
  // type 1
  type: T.Field<T>['name'] extends number?'number': 'string'|'date'
  // type 2
  // type: T[Field<T>['name']] extends number?'number': 'string'|'date'
}

const arr:Field<Req>[]=[
  {name:'stringField',type:'string'},
  {name:'dateField',type:'date'},
  {name:'numberField',type:'number'}
]

I want to either supress the error or the legal code working.

Upvotes: 1

Views: 139

Answers (1)

Iain Shelvington
Iain Shelvington

Reputation: 32244

The following type Field returns a union of all valid types by mapping each key in the passed interface to the valid object type for that key/name and then creating a union of values/types from the mapped type

Playground

interface Req{
  stringField:string,
  dateField:string,
  numberField:number
}

type Field<T> = {
  [K in keyof T]: {
    name: K;
    type: T[K] extends number ? 'number' : 'string'|'date'
  }
}[keyof T]

const arr: Field<Req>[] = [
  {name:'stringField',type:'string'},
  {name:'dateField',type:'date'},
  {name:'numberField',type: 'number'}
]

Upvotes: 1

Related Questions