TypeScript 检查字符串是否是接口中的键值
TypeScript check if a string is a key value in an interface
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
。
utility type 末尾的这一行 [keyof Obj]
获得了对象中所有值的联合。如果一些值 mathced Str
我们将得到 Str | never
。因为 never
是底部类型,并且 never
可以分配给任何类型,所以 Str | never
的并集只是 returns 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
是索引类型,而 TS 中的 interfaces
默认不索引。
您会发现更多信息 and
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
。
utility type 末尾的这一行 [keyof Obj]
获得了对象中所有值的联合。如果一些值 mathced Str
我们将得到 Str | never
。因为 never
是底部类型,并且 never
可以分配给任何类型,所以 Str | never
的并集只是 returns 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
是索引类型,而 TS 中的 interfaces
默认不索引。
您会发现更多信息