首页 > 解决方案 > TypeScript 检查字符串是否是接口中的键值

问题描述

const string = 'world';
const string2 = 'bar';
const string3 = 'test';

interface example {
  hello: 'world';
  foo: 'bar';
};

如何检查字符串是否是接口中的键值?

那么在示例中string,并且string2会通过并string3会引发错误?

谢谢!

标签: typescriptinterface

解决方案


考虑这个例子:


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(stringstring2)。如果是 -Str用作对象值,否则 - 使用never. [keyof Obj]实用程序类型末尾的这一行获取对象中所有值的并集。如果某个值计算出来Str,我们将得到Str | never. 因为never是底部类型,并且never可以分配给任何类型,所以 union of Str | neverjust 返回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 exampletype example. 我是故意这样做的,因为我已经对Assert类型应用了约束。第一个参数应该扩展RecordRecord是索引类型,而interfaces在 TS 中默认不索引。您可以在此处此处找到更多信息


推荐阅读