在TypeScript中,是否可以使用索引签名来强制执行以下结构?
{
a: { name: 'a' }, // Valid
b: { name: 'b' }, // Valid
c: { name: 'd' } // Error: Type '"d"' is not assignable to type '"c"'.
}
该对象可以使用任意字符串键接受任意数量的属性,但要求每个属性的值是一个对象,该对象本身具有可选的“ name”属性,该属性的值必须是该对象的键在父对象中分配。
可以使用字符串联合类型实现类似的功能,如下所示。但是,尚不清楚如何扩展它以将键接受为任何字符串。
type MethodNameVariant = 'GET' | 'PATCH' | 'POST' | 'DELETE';
type Methods =
{
[MethodName in MethodNameVariant]?: Method <MethodName>
};
interface Method
{
name?: MethodName;
}
任何帮助将不胜感激!
答案 0 :(得分:0)
由于string
具有无限域,并且不能轻易地用文字类型的并集表示,例如boolean
{{3 }}。 TypeScript甚至没有尝试像在can中对字符串文字的并集那样对string
进行迭代;如果尝试这样做,最终将得到类型太宽的{[k: string]: {name: string}
。
我最接近所需行为的方法是创建一个mapped types辅助函数,以检查您提供的任何对象类型的键,然后在这些键上进行映射。像这样:
const asMyType = <T extends { [K in keyof T]: { name: K } }>(t: T) => t;
因此asMyType()
仅返回其参数,但仅接受与您的约束匹配的参数。
const okay = asMyType({
a: { name: "a" },
b: { name: "b" },
c: { name: "c" }
})
const notOkay = asMyType({
a: { name: 'a' }, // Valid
b: { name: 'b' }, // Valid
c: { name: 'd' } // Error: Type '"d"' is not assignable to type '"c"'.
})
好,那是您想要的错误!这里的主要缺点是T extends {[K in keyof T]: ...
构造不像普通的旧类型那样容易处理,因为它依赖于泛型类型参数推断,但是取决于您的用例,它可能会起作用。
希望有帮助。祝你好运!