Home > Software engineering >  Create a custom type to exclude a keyof parameter
Create a custom type to exclude a keyof parameter

Time:02-18

I want to create a custom type in the typescript to be removed when I create an array of interface parameters.

type Private<T> = T

interface Test {
  param1: boolean,
  param2: number,
  param3: string,
  param4: Private<boolean>
}

type NotType<B, C> = Pick<B, {
  [K in keyof B]: B[K] extends C ? never : K
}[keyof B]>

const a: (keyof NotType<Test, Private<any>>)[] = ['param1']

But the type I created causes any value I pass to be excluded and not the ones I declared as Private, is there any way to indicate a field to be excluded without the need to declare all parameters?

CodePudding user response:

The primary problem with that is that TypeScript's type system is structural, not nominal. (This is unlike the type systems in some other languages, such as Java.) That means type compatibility is determined by the shape of the type (what kinds of properties it has), not the name of the type. Your Private<T> type doesn't do anything, the result of Private<AnyTypeHere> is AnyTypeHere. (Example.)

You could use the Exclude utility type and a literal property name:

interface Test {
    param1: boolean,
    param2: number,
    param3: string,
    param4: boolean,
}

const a: (Exclude<keyof Test, "param4">)[] = ['param1']; // works
const b: (Exclude<keyof Test, "param4">)[] = ['param4']; // fails as desired

Playground link

Or if you have several you want "private", you can create a union of them:

interface Test {
    param1: boolean,
    param2: number,
    param3: string,
    param4: boolean,
}
type TestPrivate = "param3" | "param4";

const a: (Exclude<keyof Test, TestPrivate>)[] = ['param1']; // works
const b: (Exclude<keyof Test, TestPrivate>)[] = ['param4']; // fails as desired

Playground link

I don't think there's any way you can annotate a boolean property inline with the type definition that would allow you to exclude it later except by name or type (and I don't think you want to use type for this, from the question).

  • Related