我想创建一个只允许以给定前缀开头的属性的类型:
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应该从函数参数或类型泛型参数推断您的类型