typescript 混合接口类型TS

owfi6suc  于 2022-12-14  发布在  TypeScript
关注(0)|答案(1)|浏览(244)

有一个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;
}

我收到这个错误消息,但我不完全了解“界面中的计算属性名称必须指涉型别为常值型别或'unique symbol'型别的运算式。”
任何帮助将不胜感激,因为我仍然动摇与TS

xmd2e60i

xmd2e60i1#

可以使用constAssert来防止编译器扩展list对象中值的类型:这对于编译器如何推断具有boolean类型值的键的模板文字字符串的类型是很重要的。
另外:TypeScript提供了另一种定义表示对象(具有索引值的数据结构)的类型的方法:类型别名。TS手册的类型别名和接口之间的区别一节以以下信息开始:
类型别名和接口非常相似,在很多情况下你可以自由选择。几乎interface的所有特性都可以在type中使用,关键的区别是类型不能被重新打开来添加新的属性,而接口总是可以扩展的。
如果没有理由让类型保持打开状态以供其他代码修改,那么在这种情况下,类型别名可能是更好的选择。
下面是一个例子:
注意:在下面的代码中,我启用了编译器选项noUncheckedIndexedAccess,以增强类型安全性。
TSPlayground
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

相关问题