英文:
How to coerce a function argument (object) have specific key pattern
问题
我有一个案例,需要创建一个接受具有特定键的对象的函数,这些键包含特定的值。具体来说:
type ArgType = {
name: string
selectors: {
[key: string]: Selector
}
}
在这个示例中,Selector 被定义为一个 <(state: S) => unknown>
。
然而,我想强制这个 selectors 对象具有特定的键模式,即键应该遵循 select${Capitalize<string>}
的模式,因此当涉及到该函数的参数时,参数必须符合此模式,换句话说:
Foo( {
name: "Bar",
selectors: {
selectBuzz: () => {},
fizz: () => {},
selectFizz: '123',
}
})
对象参数将报告错误,因为 "fizz" 不符合 "selectFizz" 的命名模式,同时 selectFizz 也不是一个选择器。
我该如何做到这一点?
英文:
I have a case where I need to make a function that accepts an object with specific keys, which hold specific values. Namely:
type ArgType = {
name: string
selectors: {
[key: string]: Selector
}
}
For the purpose of this example, a Selector is defined as a <S>(state: S) => unknown
However, I would like to coerce this selectors object to have a specific key pattern, namely the keys should follow the pattern of select${Capitalize<string>}
, so when the function in question receives it's arguments, the argument must conform to this pattern, or in other words:
Foo( {
name: "Bar",
selectors: {
selectBuzz: () => {},
fizz: () => {},
selectFizz: '123',
}
})
An object argument would report error for both "fizz" as it is missing the naming pattern of "selectFizz" as well as selectFizz as it is not a selector.
How would I do that?
答案1
得分: 1
自 TypeScript 4.4 起,所谓的 模式 模板字符串类型(如在 microsoft/TypeScript#40598 中实现)可以用作 索引签名 的键类型。因此,您可以这样做:
type ArgType = {
name: string,
selectors: {
[key: `select${Capitalize<string>}`]: Selector
}
}
type Selector = <S>(state: S) => unknown;
declare function Foo(a: ArgType): void;
并且它的行为如下所示:
Foo({
name: "Bar",
selectors: {
selectBuzz: () => { },
fizz: () => { }, // 直到解决下面的错误之前都不会出错
selectFizz: '123' // 错误
}
})
Foo({
name: "Bar",
selectors: {
selectBuzz: () => { },
fizz: () => { }, // 错误
selectFizz: () => { }
}
})
Foo({
name: "Bar",
selectors: {
selectBuzz: () => { },
selectFizz: () => { }
}
}) // 可行
英文:
Since TypeScript 4.4, so-called pattern template literal types (as implemented in microsoft/TypeScript#40598) can be used as the key type of an index signature. So you can do this:
type ArgType = {
name: string,
selectors: {
[key: `select${Capitalize<string>}`]: Selector
}
}
type Selector = <S>(state: S) => unknown;
declare function Foo(a: ArgType): void;
and it behaves as desired:
Foo({
name: "Bar",
selectors: {
selectBuzz: () => { },
fizz: () => { }, // not an error until you resolve the below error
selectFizz: '123' // error
}
})
Foo({
name: "Bar",
selectors: {
selectBuzz: () => { },
fizz: () => { }, // error
selectFizz: () => { }
}
})
Foo({
name: "Bar",
selectors: {
selectBuzz: () => { },
selectFizz: () => { }
}
}) // okay
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论