Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive Partial<T> in TypeScript

Tags:

typescript

I have this interface:

export interface UserSettings {     one: {         three: number;         four: number;     };     two: {         five: number;         six: number;     }; } 

...and want to turn it into this:

export interface UserSettingsForUpdate {     one?: {         three?: number;         four?: number;     };     two?: {         five?: number;         six?: number;     }; } 

...but Partial<UserSettings> produces this:

{     one?: {         three: number;         four: number;     };     two?: {         five: number;         six: number;     }; } 

Is it possible to use mapped types to make all the properties on all depths optional, or do I have to create an interface manually for that?

like image 683
Christer Carlsund Avatar asked Feb 01 '17 12:02

Christer Carlsund


People also ask

How do you use partial in TypeScript?

Partial Type in TypeScript In TypeScript, we can define a type as optional with a ? question mark. For example, in the below code, lastName is optional. Therefore, even though firstUser has the type User, we can leave out lastName as it is not required.

What means T in TypeScript?

This article opts to use the term type variables, coinciding with the official Typescript documentation. T stands for Type, and is commonly used as the first type variable name when defining generics. But in reality T can be replaced with any valid name.

What is deep partial?

Second-degree burns are injuries to the skin caused by heat, radiation, electricity, chemicals, or friction. A deep second-degree burn injures the top layer of skin (epidermis) and the tissue below the skin (dermis). This type of burn is also called a deep partial-thickness burn.


2 Answers

With the landing of Conditional Types in 2.8, we can now declare a recursive partial type as follows.

type RecursivePartial<T> = {   [P in keyof T]?:     T[P] extends (infer U)[] ? RecursivePartial<U>[] :     T[P] extends object ? RecursivePartial<T[P]> :     T[P]; }; 

Reference:

http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

like image 90
Jeffrey Patterson Avatar answered Sep 18 '22 21:09

Jeffrey Patterson


you could make your own mapping type, like this:

type RecursivePartial<T> = {     [P in keyof T]?: RecursivePartial<T[P]>; }; 

enter image description here

Unfortunately, this does not work for array-typed fields. There does not seem to be a way to do conditional type mapping yet either; i.e. limit to primitives. See https://github.com/Microsoft/TypeScript/pull/12114#issuecomment-259776847 Its possible now, see other answer.

like image 22
Meirion Hughes Avatar answered Sep 20 '22 21:09

Meirion Hughes