简体   繁体   English

用于检测重复对象中缺失属性的类型定义规则(例如多语言字段)

[英]A type-definition rule to detect missing properties in repeating objects (e.g. multi language fields)

Imagine I have a type definition like:想象一下,我有一个类型定义,例如:

export type TextMessagesType = {
  [language: string]: {
    [placeholder: string]: string;
  };
};

That would fit in this case:这适合这种情况:

export const TextMessages: TextMessagesType = {
  en: {
    noText: 'No Texts available!',
  },
};

Now, if I want to add new languages and new properties like:现在,如果我想添加新语言和新属性,例如:

export const TextMessages: TextMessagesType = {
  en: {
    noText: 'No Texts available!',
    welcome: 'You are welcome'
  },
  de: {
    noText: 'Keine weiteren Texte vorhanden!',
    // welcome missing
  },
};

I would like to ensure that the de -object has exactly the same properties as the en -object.我想确保de对象具有与en对象完全相同的属性。 The IDE should recognize the missing properties (eg, welcome ) due to type-definitions. IDE 应该识别由于类型定义而缺少的属性(例如, welcome )。

Can I do that with the assistance of typescript type definition rules?我可以在 typescript 类型定义规则的帮助下做到这一点吗? If yes, how?如果是,如何?

EDIT: Excuse me, I think, an important information is missing:编辑:对不起,我认为缺少重要信息:

The recognizing-mechanism should work dependent on existing properties in each object.识别机制应该依赖于每个 object 中的现有属性 Imagine de object has a property xy and it is missing in the en object and vice versa.想象一下de object 有一个属性xy并且在en object 中缺少它,反之亦然。 If a language object gets a new property it should be marked in all other language objects as a missing property.如果语言 object 获得新属性,则应在所有其他语言对象中将其标记为缺失属性。

We can use a union type of strings to achieve this, with the in keyword on the type of the key:我们可以使用联合类型的字符串来实现这一点,在键的类型上使用in关键字:

type RequiredLanguageFields = 'welcome'
  | 'noText';

type TextMessagesType = {
  [language: string]: {
    [placeholder in RequiredLanguageFields]: string;
  };
};

const TextMessages: TextMessagesType = {
  en: {
    noText: 'No Texts available!',
    welcome: 'You are welcome'
  },
  de: {   // type error on this line
    noText: 'Keine weiteren Texte vorhanden!',
    // welcome missing
  },
};

Property 'welcome' is missing in type '{ noText: string;类型 '{ noText: string; 中缺少属性 'welcome' }' but required in type '{ welcome: string; }' 但在 '{ welcome: string; 类型中是必需的noText: string;无文本:字符串; }'.(2741) }'.(2741)

It's a slight bit of extra work in that you need to define the required fields before you add them to the object.在将所需字段添加到 object 之前,您需要定义一些额外的工作。 Alternatively you could have some master translation object and use the keys of that to define the required keys of the others:或者,您可以进行一些主翻译 object 并使用其中的键来定义其他所需的键:

const enStrings = {
  noText: 'No Texts available!',
  welcome: 'You are welcome',
};

type TextMessagesType = {
  [language: string]: {
    [placeholder in keyof typeof enStrings]: string;
  };
};

Based on the edit to your question, I'll attempt to describe why I believe it won't be possible to create a type in the way you're looking to do it.根据对您问题的编辑,我将尝试描述为什么我认为无法以您希望的方式创建类型。

Now we're saying that all values must be objects of the same type - they must all have the same properties and all of those properties must be strings.现在我们说所有值都必须是相同类型的对象——它们都必须具有相同的属性,并且所有这些属性都必须是字符串。 But what is that type?但那是什么类型? We might define some interface which takes a generic:我们可能会定义一些采用泛型的接口:

interface ITextMessagesType<T> {
  [language: string]: {
    [placeholder in keyof T]: string;
  };
};

const TextMessages: ITextMessagesType = {    // error here as we have no passed in the type for the generic `T`
  en: {
    noText: 'No Texts available!',
    welcome: 'You are welcome'
  },
  de: {   // type error on this line
    noText: 'Keine weiteren Texte vorhanden!',
    // welcome missing
  },
};

We still need to define what that generic is;我们仍然需要定义泛型是什么; we're back to the problem you have with the original example I gave above - you need to define the keys before defining the object.我们又回到了我在上面给出的原始示例中遇到的问题——您需要在定义 object 之前定义键。

It's a little easier in a function, as we can infer the type from the object passed in. But then we're onto the next issue;在 function 中要容易一些,因为我们可以从传入的 object 中推断出类型。但接下来我们将讨论下一个问题; which object is treated as the required type?哪个 object 被视为所需类型? Take the following code as an example:以下面的代码为例:

const test = <T>(x: { [key: string]: { [key in keyof T]: string } }) => true;

const x = test({
  en: {
    noText: 'No Texts available!',
    welcome: 'You are welcome',     // now we get a type error here
  },
  de: {
    noText: 'Keine weiteren Texte vorhanden!',
    // welcome missing
  },
})

The error that we get is:我们得到的错误是:

Type '{ noText: string;键入'{ noText:字符串; welcome: string;欢迎:字符串; }' is not assignable to type '{ noText: string; }' 不可分配给类型 '{ noText: string; }'. }'。 Object literal may only specify known properties, and 'welcome' does not exist in type '{ noText: string; Object 字面量只能指定已知属性,并且 'welcome' 不存在于类型 '{ noText: string; }'.(2322) }'.(2322)

Here Typescript has determined that the value at de is the 'master' type - and as such in gives an error where we've tried to define the welcome key on en .此处 Typescript 已确定de的值是“主”类型 - 因此在我们尝试在en上定义welcome键时出现错误。

As such I don't believe you'll be able to get what you're asking for - hopefully someone will come in and prove me wrong.因此,我不相信你能得到你想要的——希望有人会进来证明我错了。

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

相关问题 类型定义:特定类型的数组,至少包含2个元素 - Type definition: An array of a certain type at least with e.g. 2 elements 如何在打字稿中导入类型定义? - How to import the type-definition in typescript? Typescript 能否确保 arrays 具有重复类型模式? 例如 [字符串,数字,字符串,数字,....(永远)] - Can Typescript ensure arrays have a repeating type pattern? e.g. [string, number, string, number, ....(forever)] ES6 class - 具有私有属性的 `this` 的 TS 类型(例如,当将 `this` 传递给回调时) - ES6 class - TS type for `this` with also the private properties (e.g. when passing `this` to callback) 如何在现有语言(例如打字稿)中添加标记? - How to add a token to an existing language (e.g. typescript)? 如何存根打字稿接口/类型定义? - How to stub a Typescript-Interface / Type-definition? react-hook-form:寄存器类型定义 - react-hook-form: register type-definition React Typescript 泛型类型重载(例如 useState) - React Typescript Generic Type Overloading (e.g. useState) 如何在 Typescript 中指定通用 class 类型的类型? (例如 typeof (AppResponse<string> ))</string> - How to specify the type of generic class type in Typescript? (e.g. typeof (AppResponse<string>)) Typescript联合类型数组作为数组函数参数,例如在$ q.all中 - Typescript union type arrays as array function parameters, e.g. in $q.all
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM