我需要定义一个类型,该类型允许将预定义键分配为类型A
,并将所有其他键分配为类型B
。
我尝试了以下操作,但出现以下错误:
type Foo = "foo";
type Bar = "bar";
interface Fuz {
[key: string]: Foo
}
interface Qux {
display?: Bar
}
type Bash = Qux & Fuz;
// ERROR: TS2322 -- Type '"bar"' is not assignable to '"foo"'
const a: Bash = {
display: "bar"
};
// ERROR: TS2322 -- Type '"foo"' is not assignable to '"bar"'
const b: Bash = {
display: "foo"
};
我想这基本上与写作相同:
interface Fuz {
// ERROR: TS2411 -- property 'display' of type '"bar"' is not assignable to string index type '"foo"'
display?: Bar
[key: string]: Foo
}
有没有办法实现上述目标?
答案 0 :(得分:1)
考虑this case:
interface Fuz {
// pretend this was valid for a moment
display: 'bar';
[k: string]: 'foo';
}
declare let x: Fuz; // lets say we have a variable of type Fuz
let index = 'display' // index is right now type string
let value = x[index]; // x[string] === 'foo' so `typeof value === 'foo'`
let value2 = x['display']; // x['display'] === 'bar' so `typeof value2 === 'bar'`
console.assert(value === value2);
// ERROR: This condition will always return 'false' since the types '"foo"' and '"bar"' have no overlap.
// which is obviously not correct, they are derived from the same property!
从定义中可以看出,您提出的value
显然包含字符串bar
,但据打字稿所理解,它实际上是foo
据我所知,没有一种方法可以提供“未明确定义的键”字段,以使x[string]
是所有适用字符串的并集。
我知道要获得所需行为的唯一方法是指定值是Foo
或在字符串键bar
的情况下是Bar
,因此字符串索引必须为联合:
interface CorrectFuz {
bar: 'bar';
[k: string]: 'bar' | 'foo';
}
对此可能有更好的解决方案,我需要有关您实际用例的更多信息以了解如何提供帮助。
答案 1 :(得分:0)
我需要定义一个类型,该类型允许将预定义键分配给类型A,并将所有其他键分配给类型B
我认为您对Typescript的期望是错误的。类型不会被“分配”给任何东西。创建类型联合时,您将通过松开类型的定义来扩展该变量的可能值,而在创建类型交集时,您将通过扩展类型的定义来限制该变量的可能值。