简体   繁体   English

TypeScript:用于A类型的索引键和用于B类型的保留键

[英]TypeScript: indexed keys to type A and reserved keys to type B

I need to define a type that allows predefined keys to be assigned to type A , and all other keys to be assigned to type B . 我需要定义一个类型,该类型允许将预定义键分配给类型A ,并将所有其他键分配给类型B

I've tried the below, but get the following errors: 我已经尝试了以下方法,但是出现以下错误:

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"
};

I guess this is fundamentally the same as writing: 我猜这基本上与写作相同:

interface Fuz {
  // ERROR: TS2411 -- property 'display' of type '"bar"' is not assignable to string index type '"foo"'
  display?: Bar
  [key: string]: Foo
}

Is there a way of achieving something like the above? 有没有办法实现上述目标?

consider 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!

As you can see with the definition you are proposing value would obviously contain the string bar but as far as typescript could understand it would really be foo 正如您在定义中所看到的那样,您提出的value显然将包含字符串bar但是据打字稿所能理解的,它确实是foo

as far as I know there isn't a way to give a "non explicitly defined keys" field so that x[string] would be the union of all applicable strings. 据我所知,还没有一种方法可以给“未明确定义的键”字段,以便x[string]是所有适用字符串的并集。

The only way I know to get the kind of behaviour you want is to specify that the values are either Foo or in the case of the string key bar it is Bar , so the string index must be a union: 我知道要获得所需行为的唯一方法是将值指定为Foo或在字符串键bar的情况下将其指定为Bar ,因此字符串索引必须为联合:

interface CorrectFuz {
    bar: 'bar';
    [k: string]: 'bar' | 'foo';
}

It is possible there is a better solution to this that I would need more information about your actual use case to know how to help though. 对此可能有更好的解决方案,我需要有关您实际用例的更多信息以了解如何提供帮助。

I need to define a type that allows predefined keys to be assigned to type A, and all other keys to be assigned to type B 我需要定义一个类型,该类型允许将预定义键分配给类型A,并将所有其他键分配给类型B

I think your expectations of Typescript are wrong. 我认为您对Typescript的期望是错误的。 Types do not get "assigned" to anything. 类型不会被“分配”给任何东西。 When you create a type union you are expanding the possible values of that variable by loosening the definition of the type, when you create a type intersection you are restricting the possible values of that variable by expanding the definition of the type. 创建类型联合时,通过松开类型的定义来扩展该变量的可能值,而在创建类型交集时,则通过扩展类型的定义来限制该变量的可能值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM