Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Type checking of optional nested properties in an interface

I want to perform type checking on nested properties in an interface, and have the following code

type PathImpl<T, K extends keyof T> = K extends string
  ? T[K] extends Record<string, any>
    ? `${K}.${Path<T[K]>}` | K
    : K
  : never;

export type Path<T> = PathImpl<T, keyof T>;

export interface User {
  name: string;
  age: number;
  dimensions: {
    height: number;
    weight: number;  
  }
  address?: {
    street: string;
    city: string;
    state: string;
  };
}

const validPath: Path<User> = 'name'; // Works fine
const alsoValidPath: Path<User> = 'address'; // Works fine
const nestedValidPath: Path<User> = 'dimensions.height'; // Yay, works fine!
const doesntWorkPath: Path<User> = 'address.street'; // Doesn't work because address is optional

Is there a way to design the Path type to also allow ‘address.street’ to be valid, although address is optional?

Playground link

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You could use the Required utility type in Path to mark all properties on the input type as required:

export type Path<T> = PathImpl<Required<T>, keyof T>;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^

Then your final assignment with "address.street" is valid because the type of Path<User> is:

| "name" 
| "age" 
| "dimensions" 
| "address" 
| "dimensions.height" 
| "dimensions.weight" 
| "address.street" 
| "address.city" 
| "address.state"

Playground link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading