创建自定义类型以排除 keyof 参数

Create a custom type to exclude a keyof parameter

我想在打字稿中创建一个自定义类型,以便在创建接口参数数组时删除。

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']

但是我创建的类型导致我传递的任何值都被排除,而不是我声明为私有的值,有没有什么方法可以指示要排除的字段而不需要声明所有参数?

主要问题是 TypeScript 的类型系统是结构,而不是名义。 (这与某些其他语言中的类型系统不同,例如 Java。)这意味着类型兼容性由类型的 shape 决定(它具有哪些类型的属性),而不是类型的 name。您的 Private<T> 类型不执行任何操作,Private<AnyTypeHere> 的结果是 AnyTypeHere。 (Example.)

您可以使用 Exclude 实用程序类型和文字 属性 名称:

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

或者如果您有多个想要“私有”,则可以创建它们的联合:

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

我认为没有任何方法可以将 boolean 属性 与类型定义内联注释,这样您以后就可以排除它,除非按名称或类型(我不这样做)从问题来看,你不认为你想为此使用类型。