Typescript 泛型中的“不在 keyof 中”

Pag*_*und 5 typescript typescript-generics

创建一个类型,其中每个属性Type现在都属于类型boolean

type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
};
Run Code Online (Sandbox Code Playgroud)

现在我想扩展这一点:所有不在 中 Type的属性(如果存在)都必须是类型string。像这样的东西:

type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
  [Property not in keyof Type]?: string;
};
Run Code Online (Sandbox Code Playgroud)

对此正确的做法是什么?

Tob*_* S. 4

独立类型可能无法在这里工作。您正在寻找的基本上是这样的:

type OptionsFlag<T> = {
  [K in keyof T]: boolean
} & {
  [K in Exclude<string, keyof T>]: string
}
Run Code Online (Sandbox Code Playgroud)

但这在 TypeScript 中还不起作用。因为Exclude<string, keyof T>计算结果string将是索引签名。您无法使用此类型构造对象,因为每个属性的类型都必须满足两个索引签名要求,string & boolean这是不可能的。

我能想到的唯一解决方法是:

type Type = {
  a: string
  b: string
  c: string
}

type OptionsFlag<T, S> = {
  [K in keyof T]: K extends keyof S ? boolean : string
}

function f<T>(obj: OptionsFlag<T, Type>) {}

f({
  a: true,
  b: true,
  c: "abc", // error because c is in Type and string
  d: "abc",
  e: "abc",
  f: true   // error because f is not in type and boolean
})
Run Code Online (Sandbox Code Playgroud)

操场

我们可以使用函数的泛型类型来映射传递类型的每个属性T。然后我们检查每个属性T是否属于S并相应地调整类型。

S这有一个主要缺点:当我们声明函数时必须知道 的类型。正如您所看到的,我将类型放入Type函数OptionsFlag<T, Type>声明中,而不是使用第二个泛型类型。TypeScript 尚不支持部分类型推断,因此我们不能让 TypeScriptT在调用函数时推断并手动指定第二个泛型类型。