typescript - TypeScript 检查字符串是否是接口中的键值
问题描述
const string = 'world';
const string2 = 'bar';
const string3 = 'test';
interface example {
hello: 'world';
foo: 'bar';
};
如何检查字符串是否是接口中的键值?
那么在示例中string
,并且string2
会通过并string3
会引发错误?
谢谢!
解决方案
考虑这个例子:
const string = 'world';
const string2 = 'bar';
const string3 = 'test';
interface example {
hello: 'world';
foo: 'bar';
};
type IsAValue<Obj, Str extends string> = {
[Prop in keyof Obj]: Str extends Obj[Prop] ? Str : never
}[keyof Obj]
type Result1 = IsAValue<example, 'world'> // world
type Result2 = IsAValue<example, 'bar'> // bar
type Result3 = IsAValue<example, 'test'> // never
IsAValue
:
Prop
- 代表每个键
Obj
- 代表一个对象,在我们的例子中它是example
接口。
此实用程序类型遍历每个Obj
( example
) 键并检查是否Obj[Prop]
扩展了第二个参数Str
(string
或string2
)。如果是 -Str
用作对象值,否则 - 使用never
. [keyof Obj]
实用程序类型末尾的这一行获取对象中所有值的并集。如果某个值计算出来Str
,我们将得到Str | never
. 因为never
是底部类型,并且never
可以分配给任何类型,所以 union of Str | never
just 返回Str
。
如果您只想从中获取布尔值IsAValue
,我的意思是true
- 值存在,false
- 不存在。您可以只添加条件类型,它将检查结果是否扩展never
:
const string = 'world';
const string2 = 'bar';
const string3 = 'test';
interface example {
hello: 'world';
foo: 'bar';
};
type IsNever<T> = [T] extends [never] ? true : false
type IsAValue<Obj, Str extends string> = IsNever<{
[Prop in keyof Obj]: Str extends Obj[Prop] ? Str : never
}[keyof Obj]> extends false ? true : false
type Result1 = IsAValue<example, 'world'> // true
type Result2 = IsAValue<example, 'bar'> // true
type Result3 = IsAValue<example, 'test'> // false
如果你想抛出一个错误,看这个例子:
const string = 'world';
const string2 = 'bar';
const string3 = 'test';
type example = {
hello: 'world';
foo: 'bar';
};
type Values<T> = T[keyof T]
type Assert<Obj extends Record<string, string>, Key extends Values<Obj>> = Obj
type Result1 = Assert<example, 'world'> // true
type Result2 = Assert<example, 'bar'> // true
type Result3 = Assert<example, 'test'> // false
您可能已经注意到,我已替换interface example
为type example
. 我是故意这样做的,因为我已经对Assert
类型应用了约束。第一个参数应该扩展Record
。Record
是索引类型,而interfaces
在 TS 中默认不索引。您可以在此处和此处找到更多信息
推荐阅读
- grafana - 在 InfluxQL 中计算值和(移动)平均值之间的差异
- python - 如何在 Python 3x 中以垂直和水平方式格式化列表?
- python-3.x - 尝试从 FourSquare API 调用所有素食餐厅
- r - R:计算长/纬度和形状文件之间距离的较少计算密集型方法
- python - Python/Selenium 在未找到时尝试对元素使用“if”语句
- python - 验证并处理错误以将有意义的状态传递回客户端
- python - 在 Pandas 中拆分字符串忽略大小写
- java - 带有 OpenJDK 11 的 Tomcat 9 无法识别任何 Spring 应用程序
- r - 基于 NA 有条件地删除重复项
- java - ZonedDateTime 与时区添加到打印格式