简体   繁体   English

Typescript泛型中的“不在keyof中”

[英]"Not in keyof" in Typescript generics

Creates a type where each property from Type is now of type boolean :创建一个类型,其中Type中的每个属性现在都是boolean类型:

type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
};

Now I want to extend this: All properties not in Type , if present, must be of type string .现在我想扩展它:不在Type中的所有属性(如果存在)必须是string类型。 Something like this:像这样的东西:

type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
  [Property not in keyof Type]?: string;
};

What is the correct approach to this?对此的正确方法是什么?

A stand-alone type will probably not work here.单机类型在这里可能不起作用。 What you are looking for is basically this:你要找的基本上是这样的:

type OptionsFlag<T> = {
  [K in keyof T]: boolean
} & {
  [K in Exclude<string, keyof T>]: string
}

But this does not work (yet) in TypeScript.但这在 TypeScript 中(还)不起作用。 Because Exclude<string, keyof T> evaluates down to string and will be an index signature.因为Exclude<string, keyof T>计算结果为string并将成为索引签名。 You can not construct an object with this type because every property's type will have to fulfill both index signature requirements string & boolean which is not possible.您不能使用此类型构造对象,因为每个属性的类型都必须同时满足索引签名要求string & boolean ,这是不可能的。

The only work-around I could think of is this:我能想到的唯一解决方法是:

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
})

Playground 操场

We can use a generic type of a function to map over each property of the passed type T .我们可以使用函数的泛型类型来映射传递的类型T的每个属性。 We then check for each property of T if it belongs to S and ajust the type accordingly.然后我们检查T的每个属性是否属于S并相应地调整类型。

This has a major drawback: The type of S must be known when we declare the function.这有一个主要缺点:当我们声明函数时,必须知道S的类型。 As you can see, I put the type Type in OptionsFlag<T, Type> in the function declaration instead of using a second generic type.如您所见,我在函数声明中将类型Type放在OptionsFlag<T, Type>中,而不是使用第二个泛型类型。 TypeScript does not yet support partial type inference, so we can't let TypeScript infer T and manually specify a second generic type when we call the function. TypeScript 尚不支持部分类型推断,因此我们不能让 TypeScript 推断T并在调用函数时手动指定第二个泛型类型。

Since the mapped type can only access keys live within Type, you need to provide an extra Generic Type for comparison.由于映射类型只能访问存在于 Type 中的键,因此您需要提供额外的 Generic Type 进行比较。

type OptionsFlags<T extends {}, K extends string> = {
  [k in K]: k extends keyof T ? boolean : string;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM