简体   繁体   English

根据 object 中另一个键的值强制执行特定类型的键(可区分联合)

[英]Enforce a specific type of a key based on the value of another key in the object (Discriminated unions)

Maybe the title of the question wasn't so explicit what about I want, but what I want is something called discrimnated unions , I think.也许问题的标题并没有那么明确我想要什么,但我想我想要的是一种叫做歧视性工会的东西。 It's documented here: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions它记录在这里: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions

A have a type A, with two fields, B and C, the type of the field B is well-defined set of string literals and I want that the type of C be in reason of the value from the field B. A 有一个类型 A,有两个字段 B 和 C,字段 B 的类型是明确定义的字符串文字集,我希望 C 的类型是由于字段 B 的值。

Some code to better explain:一些代码可以更好地解释:

type Field1Values = "a" | "b" | "c";

type TypeForValueA = {
   ...
}

type TypeForValueB = {
   ...
}

type TypeForValueC = {
   ...
}

type RootType = {
    field1: Field1Values,
    field2: <something here that I didn't know exactly what to put>
}


const objA: RootType = {
    field1: "a",
    field2: {
        // Only the values from the type TypeForValueA are allowed
    }

}

const objB: RootType = {
    field1: "b",
    field2: {
        // Only the values from the type TypeForValueB are allowed
    }

}

How can I achieve the effect that I want?怎样才能达到我想要的效果?

Thanks谢谢

Edit:编辑:

I already tried like in the docs我已经在文档中尝试过

type NetworkState =
  | NetworkLoadingState
  | NetworkFailedState
  | NetworkSuccessState;

And the lint shows me all the fields from all the types, I want that only the fields from the correct type be shown lint 显示了所有类型的所有字段,我希望只显示正确类型的字段

I've created a playground link demonstrating an answer .我创建了一个游乐场链接来展示答案

The problem with your original approach is that it doesn't communicate any mapping between the discriminating field's set of possible values and the discriminated field's possible set of types.您原始方法的问题在于,它没有在鉴别字段的可能值集和鉴别字段的可能类型集之间进行任何映射。 All I did was adapt your example to follow the TypeScript docs you linked.我所做的只是调整您的示例以遵循您链接的 TypeScript 文档。

// type Field1Values = "a" | "b" | "c"; // no longer needed

type TypeForValueA = {
   fieldForA: string;
}

type TypeForValueB = {
   fieldForB: number;
}

type TypeForValueC = {
   fieldForC: boolean;
}

type RootA = {
    field1: "a";
    field2: TypeForValueA;
}
type RootB = {
    field1: "b";
    field2: TypeForValueB;
}
type RootC = {
    field1: "c";
    field2: TypeForValueC;
}
type RootType = RootA | RootB | RootC;


const objA: RootType = {
    field1: "a",
    // field2: press `ctrl+space` for suggestions
}
const objB: RootType = {
    field1: "b",
    // field2: press `ctrl+space` for suggestions
}
const objC: RootType = {
    field1: "c",
    // field2: press `ctrl+space` for suggestions
}

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

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