Home > front end >  How to dynamically make properties of a dynamic type optional?
How to dynamically make properties of a dynamic type optional?

Time:01-22

I know there is a way to generate a type dynamically: Typescript dynamically create types based on object

But I can't find a way to make some properties of the dynamically generated type optional.

For example, say I have a object

const obj = {
  keyName1: {
     type: 'string',
     required: true
  },
  keyName1: {
     type: 'string',
     required: false
  },
}

How do I make a type based on this object? Given that some properties are optional (if required is false).

If I simply have this object:

const obj = {
  keyName1: 'string'
}

I could make a type with:

  type Generate<T> = T;
  type Generated = Generate<typeof myObj> 

But with optional parameters, I don't know how...

CodePudding user response:

You'll first need a utility type mapping each type string (eg 'string') to its type (string).

Then, map the object properties and do Obj[K]['required'] extends true ? to conditionally check whether to alternate with undefined or not. See this answer for how to separate out the optional properties from the non-optional properties in the new object.

const obj = {
  keyName1: {
    type: 'string',
    required: true
  },
  keyName2: {
    type: 'number',
    required: false
  },
} as const;
type Obj = typeof obj;
type TypesByTypeof = {
    'string': string;
    'number': number;
}

type ObjType = {
  [key in keyof Obj as Obj[key]['required'] extends true ? key : never]: TypesByTypeof[Obj[key]['type']]
} & {
  [key in keyof Obj as Obj[key]['required'] extends false ? key : never]?: TypesByTypeof[Obj[key]['type']]
}

Result:

type ObjType = {
    readonly keyName1: string;
} & {
    readonly keyName2?: number | undefined;
}
  •  Tags:  
  • Related