打字稿限制对象属性的数量

打字稿限制对象属性的数量

本文介绍了打字稿限制对象属性的数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to restrict the count of object properties, say I want to restrict object have only one string propery (with any name), I can do:

{[index: string]: any}

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

to restrict the type of property, but can one restrict also the count of properties?

推荐答案

这个问题在Stackoverflow上有很多答案(包括这个详细的一个),但它们都不适用于我的情况,这与此处发布的情况类似.

There are many answers to this question on Stackoverflow (including this detailed one), but none of them worked for my situation, which is similar to the one posted here.

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

I have a function that takes an object. I want it to throw a Compilation Error (Typescript) if the passed object doesn't have exactly one key. e.g.

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,我是通过以下实用函数实现的.


Solution

Using the popular UnionToIntersection and IsUnion, I achieved it via the following utility function.

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!

这篇关于打字稿限制对象属性的数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 05:38