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]
行获得对象中所有值的并集。如果对CCD_ 17求一些值,则得到CCD_。因为never
是底部类型,而never
可分配给任何类型,所以Str | never
的并集只返回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
游乐场
你可能已经注意到了,我已经用type example
替换了interface example
。我特意做了这个,因为我对Assert
类型应用了一个约束。第一个参数应该扩展Record
。CCD_ 31是索引类型,而TS中的CCD_。更多信息,你可以在这里和这里找到