- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试编写一个通用函数,它可以通过键名切换任何对象中的 bool 属性。我读了release notes for TypeScript-2.8并认为条件类型应该可以解决此类问题。但是,我不知道如何编写我的函数。
我的函数接受要修改的对象和要修改的键的名称。为了确保只传入 bool 属性的键,我使用了条件类型表达式 T[K] extends boolean ? K:从不
。据我了解,如果我尝试为非 bool 属性传递 key ,这应该会导致错误,因为 T[K]
不满足 extends boolean
。但是,如果我尝试为 bool 值传递 key ,那么它应该接受 K
。
然而,即使有这个条件,TypeScript 似乎也没有在函数内意识到 T[K] extends boolean
必须为真。所以我无法将从对象读取的值赋值回对象。这会导致下面显示的第一个错误。第二个错误是类型推断似乎对我的函数不起作用。在下面的调用中,到目前为止只有第二个调用通过了 TypeScript 的检查。
function invertProperty<T, K extends keyof T> (o:T, propertyName:(T[K] extends boolean ? K : never)) {
o[propertyName] = !o[propertyName]; // Type 'false' is not assignable to type 'T[T[K] extends boolean ? K : never]'. [2322]
}
const myObject:IObject = {
a: 1,
b: true,
c: 'hi',
};
invertProperty(myObject, 'b'); // Argument of type '"b"' is not assignable to parameter of type 'never'. [2345]
invertProperty<IObject, 'b'>(myObject, 'b'); // Works, but requires me to type too much.
invertProperty(myObject, 'a'); // Argument of type '"a"' is not assignable to parameter of type 'never'. [2345]
invertProperty<IObject, 'a'>(myObject, 'a'); // Argument of type '"a"' is not assignable to parameter of type 'never'. [2345]
interface IObject {
a:number,
b:boolean,
c:string,
}
我认为,如果在我的 K extends keyof T
类型约束中,我也可以声明 and T[K] extends boolean
它会做正确的事情。在我看来,这是一个问题,我试图在参数类型中使用 never
而不是能够约束类型参数。但我找不到任何方式来表达这一点。
关于如何在完全类型安全的情况下实现这一点有什么想法吗?
最佳答案
首先,您可以使用此构造提取 bool 属性的所有键(它将非 bool 值的键转换为 never
并采用所有键/never 的联合,使用 T | never
是 T
):
type BooleanKeys<T> = { [k in keyof T]: T[k] extends boolean ? k : never }[keyof T];
然后,为了使 TypeScript 乐于为属性分配 bool 值,您引入了声明为仅具有 bool 属性的中间类型(不幸的是,TypeScript 无法自行解决这部分问题)
type OnlyBoolean<T> = { [k in BooleanKeys<T>]: boolean };
并且您声明 invertProperty
的泛型类型参数与 OnlyBoolean
兼容(确实如此,它可能包含额外的非 bool 属性,但没关系)
注意您可能需要不同版本的代码,具体取决于编译器的版本,此答案中的原始代码已停止使用 TypeScript 3.2:
// for TypeScript 3.1 or earlier
function invertProperty<T extends OnlyBoolean<T>>(o: T, propertyName: BooleanKeys<T>) {
o[propertyName] = !o[propertyName];
}
// for TypeScript 3.2 or later
function invertProperty<T>(o: OnlyBoolean<T>, propertyName: keyof OnlyBoolean<T>) {
o[propertyName] = !o[propertyName];
}
interface IObject {
a: number;
b: boolean;
c: string;
}
const myObject:IObject = {
a: 1,
b: true,
c: 'hi',
};
invertProperty(myObject, 'b'); // ok
invertProperty(myObject, 'a'); // error
关于typescript - 我如何要求 keyof 用于特定类型的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50851263/
我有一个使用 keyof 特性的简单函数: interface B { name: string; age: number; } function test(key: keyof B) {}
class Car { engine:number; detials:{ good:'Boy' } } 类 ModelProperty当使用 new Model
遇到以下代码: type RequireOnlyOne 如果有人能解释什么是 keyof T = keyof T,我们将不胜感激? 最佳答案 这意味着该函数采用一个必需的类型参数 T 和一个可选的类型
在 TypeScript 中,一些类型是使用 extends keyof 定义的或 in keyof .我试图理解它们的意思,但到目前为止我没有成功。 我得到的是 keyof alone 返回一个联合
下面的 typescript 定义有区别吗: function prop(obj: T, key: K) { return obj[key]; } 和 function prop2(obj:
假设我有一个为一组数据定义有效值的接口(interface): interface Foo { bar: boolean; } 而且我希望一个类能够使用一种方法公开该数据。我发现如果我使用 key
这是错误还是我误解了 typescript 的东西? 示例代码如下: type Omit = Pick>; const func = () => { const aWithoutB: Omit =
我想从配置对象推断出此对象类型中 on 下所有键的联合: type Config = { initial: string; states: { idle: { on: {
我在理解字符串枚举在使用它们索引类型时的行为方式时遇到了一些问题。似乎有时 TS 认识到字符串枚举的值是某种类型的 keyof 的扩展,而其他时候则不然。举例说明: enum Key { FO
我有以下代码: const KeyboardEventKeys = { Escape: 'Escape', Enter: 'Enter', Tab: 'Tab' }; type Keybo
我正在尝试用 Typescript 编写一个函数,它需要: 一个对象,它至少有一个 X 类型的成员(在这个例子中: bool 值) 指向所述值的对象的键 (eg. {someValue: true}
如果我有以下类型 interface Foo { bar: string; baz: number; qux: string; } 我可以使用 typeof 来键入一个参数,这
例如。给定以下代码。我在最后一个 compat[k] 上收到 typescript 错误,错误说 Type 'keyof T' cannot be used to index type 'Partia
创建一个类型,其中 Type 中的每个属性现在都是 boolean 类型: type OptionsFlags = { [Property in keyof Type]: boolean; };
我想定义一个适配器架构,将一个对象转换为另一个。 export type AdapterSchema = { [key in keyof Partial]: { target:
我有一个按键嵌套的对象,如下所示: const OBJECTS = { OBJECT1: { properties: { prop1: { value:
我正在努力编写一个代码来推断 args.value 的类型里面if范围: class Foo { public id: number; public name: string;
我正在尝试编写一个通用函数,它可以通过键名切换任何对象中的 bool 属性。我读了release notes for TypeScript-2.8并认为条件类型应该可以解决此类问题。但是,我不知道如何
发现很难清楚地解释这一点。 在下面的 Setter 界面中,我将“field”键的类型限制为 keyof Store(在本例中为“name”|“age”)。 然后对于“值”键,我想获取给定“字段”键的
我有一个抽象类 export abstract class ABaseModel { public static isKeyOf(propName: (keyof T)): string {
我是一名优秀的程序员,十分优秀!