每个属性的带前缀的映射类型



我想创建一个只允许以给定前缀开头的属性的类型:

const example = {
'#prop1': () => {},
'#prop2': () => {}
} 

因此,在这种情况下,每个Property都必须以#为前缀。我玩过»模板文字类型«在»映射类型«像这样:

interface WithD {
[s: `#${string}`]: () => void
}

但这就产生了这样的错误:

索引签名参数类型必须是"string"或"number"。

有什么办法做到这一点吗?

正如@Nadia Chibrikova所说,如果事先不知道example的值,就无法构建WithD

处理它的唯一方法是知道(能够推断(要验证的类型。


type Validation<T extends Record<string, any>> = {
[Prop in keyof T]: Prop extends `#${string}` ? T[Prop] : never
}
type Assert<T, U> = T extends U ? U extends T ? true : false : false

const example1 = {
'#prop1': () => { },
'#prop2': () => { },
}
const example2 = {
...example1,
'prop3': () => { }
}
type Example1 = typeof example1;
type Example2 = typeof example2;

type Result1 = Assert<Example1, Validation<Example1>> // true
type Result2 = Assert<Example2, Validation<Example2>> // false

const isValid = <T extends Validation<T>>(arg: T) => { }
isValid(example1) // ok
isValid(example2) // expected error

游乐场

因此,TS应该从函数参数或类型泛型参数推断您的类型