typescripttypestypescript-typingstype-narrowing

Create union type for keys of properties with specific shape


I have this object structure SomeParamList, where the key is a string and the values may be undefined or a on object of arbitrary key value pairs. I want to specify a union type of the object keys that only include the ones where the value has at least { password: string } in it.

type SomeParamList = {
  FirstScreen: undefined,
  SecondScreen: {someParam: string}
  ThirdScreen: {password: string, name: string},
  FourthScreen: {password:string}
}

type KeysWithPass = ...
//   ^?  "ThirdScreen" | "FourthScreen" 

EDIT:

What I have tried so far is this:

type Narrowed<T, U> = {
  [K in keyof T]: T[K] extends U ? T[K] : never;
};

It returns an object where all properties are never where the type does not extend. But when I try to do keyof of this, it just returns the original type.


Solution

  • You should can use key remapping to filter out the correct properties inside a mapped type. Using keyof on the resulting type will return the string literal types you are looking for.

    type Narrowed<T, U> = keyof {
      [K in keyof T as T[K] extends U ? K : never]: any;
    };
    
    type KeysWithPass = Narrowed<SomeParamList, { password: string }>
    // type KeysWithPass = "ThirdScreen" | "FourthScreen"
    

    Playground