混合接口类型TS.



有一个TS问题,我认为会比它更容易实现。我有一个接口,它描述了一个键/值的对象,大多数字符串有一个例外。它是一个很长的列表,比如

export const list = {
itemOne: 'bla',
itemTwo: 'bla bla',
itemThree: 'bla bla bla',
itemFour: false

}

我想要一个这样的接口,而不需要显式地输入每个条目,比如

import { list as keys } from 'the_above'
interface listTypes { 
[key: string]: string;
[`${keys.itemFour}`]: boolean;
}

我得到这个错误信息,我不完全理解'接口中的计算属性名称必须引用其类型为文字类型或'唯一符号'类型的表达式。'

任何帮助将是感激的,因为我仍然摇摇欲坠的TS

您可以使用const断言来防止编译器扩大list对象中值的类型:编译器将推断文字值。这对于编译器如何推断具有boolean类型值的键的模板字面值字符串的类型非常重要。

Also: TypeScript提供了另一种方式来定义表示对象(带索引值的数据结构)的类型:类型别名。TS手册的类型别名和接口的区别一节以以下信息开始:

类型别名和接口非常相似,在许多情况下,您可以在它们之间自由选择。几乎所有interface的特性都可以在type中获得,关键的区别是类型不能重新打开以添加新属性,而接口总是可扩展的。

如果没有理由需要保持类型打开以被其他代码更改,那么在这种情况下,类型别名可能是更好的选择。

下面是一个例子:

注意:在下面的playground和代码中,我已经启用了编译器选项noUncheckedIndexedAccess以获得更强的类型安全性。参见实用程序类型Record<Keys, Type>

TS操场

module1.ts:

export const list = {
itemOne: 'bla',
itemTwo: 'bla bla',
itemThree: 'bla bla bla',
itemFour: false,
} as const;
//^^^^^^^^
// const assertion

module2.ts:

import { list as keys } from './module1';
type ListTypes = Record<string, string> & Record<`${typeof keys['itemFour']}`, boolean>;

下面是一些显示编译器推理的示例语句:它们说明了类型代表了你在问题中所询问的内容:

type ListTypeKeyWithBooleanValue = keyof {
[
K in keyof ListTypes as ListTypes[K] extends boolean
? K
: never
]: unknown;
};
declare const k: ListTypeKeyWithBooleanValue;
//^? const k: "false"
declare const l: ListTypes;
l.false;
//^? (property) false: boolean
l.true;
//^? string | undefined
l.anotherProperty;
//^? string | undefined

最新更新