Typescript:允许任何以特定字符串开头的属性

Typescript:允许任何以特定字符串开头的属性,typescript,Typescript,我需要分配具有唯一名称的属性,所有属性都以字符串开头,比如meta 我该如何为此编写一个类型 type MyType = { knownProp: string, [key: TypeForAnyStringThatStartsWithMeta_]: string, // how to define a type to use here? } 您可以从4.1中执行此操作,并且它与您所能达到的最接近 type MetaMatch = `meta_${string}` const foo

我需要分配具有唯一名称的属性,所有属性都以字符串开头,比如
meta

我该如何为此编写一个类型

type MyType = {
  knownProp: string,
  [key: TypeForAnyStringThatStartsWithMeta_]: string, // how to define a type to use here?
}

您可以从4.1中执行此操作,并且它与您所能达到的最接近

type MetaMatch = `meta_${string}`

const foo : MetaMatch = "meta_hello_world" //ok
const bar : MetaMatch = "hello_world" // error
您可以使用其中的模式(由实现)来表示该形式的字符串:

type AllowedKeys = `meta_${string}`

function foo(k: AllowedKeys) { }

foo("meta_okay") // okay
foo("not_okay") // error!
// Argument of type '"not_okay"' is not assignable 
// to parameter of type '`meta_${string}`'.

遗憾的是,当前无法使用模式模板文本作为键定义对象类型。您希望能够写出以下内容:

type Oops = Record<AllowedKeys, unknown>;
// type Oops = {}
const hmm: Oops = { meta_okay: 123 }; // fine, but
const oops: Oops = { not_okay: 123 }; // NO ERROR!  uh oh
键入Oops=记录。有关更多信息,请参阅。这可能最终会得到解决,但我不确定


这意味着当前没有特定的对象类型可以按您想要的方式运行。作为一种变通方法,您可以编写一个表示约束的类型,然后使用帮助器函数验证潜在候选对象:

type ValidObj<T> = { [K in keyof T]: K extends AllowedKeys ? T[K] : never };
const asValidObj = <T extends ValidObj<T>>(t: T) => t;

const okay = asValidObj({ meta_okay: 123, meta_also_okay: 456 });
const notOkay = asValidObj({ meta_okay: 123, not_okay: 456 }); // error!
// ----------------------------------------> ~~~~~~~~
// Type 'number' is not assignable to type 'never'.
type ValidObj={[K in keyof T]:K扩展了允许的键?T[K]:never};
常数asValidObj=(t:t)=>t;
const okay=asValidObj({meta_okay:123,meta_也_okay:456});
const notOkay=asValidObj({meta_ok:123,not_ok:456});//错误!
// ----------------------------------------> ~~~~~~~~
//类型“number”不可分配给类型“never”。
因此,您不能编写
const-obj:ValidObj={…}
,而必须编写
const-obj=asValidObj({…})
。除非microsoft/TypeScript#42192得到解决,否则这可能是您所能做的最好的事情


尝试按如下方式使用它:
类型MarkedText={[key:MetaMatch]:string}
和TS给出两个错误:“TS1110:type expected”和“TS2693:'string'仅指类型,但在此处用作值。”映射类型需要
输入。但看看@jcalz的答案,它给出了一个更全面的示例,说明了如何以类型安全的方式使用它。使用泛型+辅助对象。