如何使用 TypeScript 泛型检查一个对象是否包含某个值?

huangapple go评论62阅读模式
英文:

How to check whether an object contains a value with TypeScript generics?

问题

我一直在尝试创建一种方法来检查从数据库提供的值是否满足作为枚举的一部分。一开始我只想提供一个通用的 TypeGuard,然后我决定提供一个函数,不仅检查值是否属于枚举,还提供对两种情况的处理。然而,TypeScript 显然不允许在泛型声明中提供 <E extends Enum>,所以我决定像这样检查一个对象 <T extends Object>,这更抽象,我认为这是一个受欢迎的特性。

typeGuard<E extends Object>(value: string): value is E {
  return Object.values(E).includes(value);
}

然后,它理所当然地不起作用,因为我不能简单地将 E 传递给 Object.values(),因为它不是一个对象,而只是一种类型。一种方法是将对象作为另一个参数传递,但是对我来说,这感觉有点臃肿,因为我不会以其他方式使用这个对象。对于仅想将其用作函数而不是类型守卫的情况,同样存在相同的问题。

typeGuard<E extends Object>(values: string): boolean {
  return Object.keys(E).includes()
}

TL;DR - 有没有一种方法可以仅通过检查对象的类型而不是对象本身来检查给定值是否代表在对象中的值?

英文:

I've been trying to create a way of checking whether a value provided from the database satisfies being a part of an enum. I first wanted to provide just a generic TypeGuard, then I decided it would also be nice to provide a function to not only check the value against the enum, but also provide some handling for both cases. However, TypeScript apparently doesn't allow you to provide <E extends Enum> in the generics declaration, so I just decided to check against an object like so <T extends Object>, which would be even more abstract, which I'd say is a welcome feature.

typeGuard&lt;E extends Object&gt;(value: string): value is E {
  return Object.values(E).includes(value);
}

then it understandably doesn't work, since I can't just pass E to Object.values(), since it isn't an object, but only a type. One way would be to pass the object as another argument, however, that feels kind of bulky to me, since I'm not going to be using the object any other way. Same problem persists for only wanting to use it as a function, not a type guard.

typeGuard&lt;E extends Object&gt;(values: string): boolean {
  return Object.keys(E).includes()
}

TL;DR - is there a way to check whether a given value is a value representing in an object just by checking the TYPE of an object and not the object itself?

答案1

得分: 1

Well, NO, because typescript compilers pass NO type information into runtime.

There are ways to pass static types into runtime (using transformers), but
I doubt that will work with passing the type into generic call


The recommended way to check if the object matches whatever (deep) type properly would be using Zod, or a newer https://arktype.io/ . They have quite a bit of boilerplate (esp. Zod), but allows to ensure that objects are proper ones
ArkType has more somple boilerplate and allows to easily infer TS typedefs from validator defs, so I recommend cheching that

英文:

Well, NO, because typescript compilers pass NO type information into runtime.

There are ways to pass static types into runtime (using transformers), but
I doubt that will work with passing the type into generic call


The recommended way to check if the object matches whatever (deep) type properly would be using Zod, or a newer https://arktype.io/ . They have quite a bit of boilerplate (esp. Zod), but allows to ensure that objects are proper ones
ArkType has more somple boilerplate and allows to easily infer TS typedefs from validator defs, so I recommend cheching that

huangapple
  • 本文由 发表于 2023年4月16日 23:02:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76028528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定