typescript 限制对象属性的数量

标签 typescript

是否可以限制对象属性的数量,比如我想限制对象只有一个字符串属性(任意名称),我可以这样做:

{[index: string]: any}

可以限制属性的类型,但是可以限制属性的数量吗?

最佳答案

这个问题在 Stackoverflow 上有很多答案(包括 this detailed one ),但没有一个适合我的情况,这与此处发布的情况类似。

问题

我有一个接受对象的函数。如果传递的对象没有一个键,我希望它抛出一个编译错误 (Typescript)。例如

f({}); // Must error here, as it has less than one key!
f({ x: 5 });
f({ x: 5, y : 6 }); // Must error here, as it has more than one key!

解决方案

使用流行的 UnionToIntersectionIsUnion ,我通过以下实用函数实现了它。

type SingleKey<T> = IsUnion<keyof T> extends true ? never : {} extends T ? never : T;

完整代码:

// From https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// From: https://stackoverflow.com/a/53955431
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;

// Here we come!
type SingleKey<T> = IsUnion<keyof T> extends true ? never : {} extends T ? never : T;

// Usage:
function f<T extends Record<string, any>>(obj: SingleKey<T>) {
    console.log({ obj });
}

f({}); // errors here!
f({ x: 5 });
f({ x: 5, y : 6 }); // errors here!

Playground Link

关于 typescript 限制对象属性的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39190154/

相关文章:

arrays - TypeScript - 数组 toString()

typescript - 我可以从 Typescript 中的类型中提取可选属性吗?

typescript - 更改从类型定义导入的类型

javascript - 原子 'autocomplete+' 不工作

javascript - TypeScript 可更新和枚举引用

typescript - 如何根据 TypeScript 中 const 对象的键/值创建对象类型?

typescript - 工作函数,即使它返回错误的类型

javascript - 导入别名 'theme'的循环定义

angular - 如果 '<x>' 是一个 Angular 组件,那么验证它是这个模块的一部分

angular - 使用 ngClick 更改 ngFor 中的元素