选择特定的键并与相同的键减少。

huangapple go评论62阅读模式
英文:

Pick specific keys and reduce with same keys

问题

我有一个用例,需要生成一个继承特定键的另一个类的类型的接口,并从那里构建。我需要使用这个继承的类型,但也需要通过JS将数据减少到继承类型的实例中。有没有一种方法只需要列出这些键一次?

我目前是这样做的:

interface IPrimaryType {
  key1: string;
  key2: string;
  key3: string;
  key4: string;
  key5: string;
  key6: string;
  key7: string;
}

interface ISecondaryType {
  thisDoesntMatter: string;
}

interface ITertiaryType {
  thisDoesntMatter: string;
}

interface IInheritedType extends Pick<IPrimaryType, 'key1' | 'key2' | 'key3' | 'key4' | 'key5'> {
  secondaryData: ISecondaryType;
  tirtiaryData?: ITertiaryType | null;
}

const inheritedKeys = ['key1', 'key2', 'key3', 'key4', 'key5'];

const primaryObj = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3',
  key4: 'value4',
  key5: 'value5',
  key6: 'value6',
  key7: 'value7',
};
const secondaryData = { thisDoesntMatter: '' };
const tirtiaryData = { thisDoesntMatter: '' };

let inheritedObj = inheritedKeys.reduce(
  (acc, key: string) => ({ ...acc, [key]: (primaryObj as any)[key] }),
  {} as IInheritedType
);
inheritedObj.secondaryData = secondaryData;
inheritedObj.tirtiaryData = tirtiaryData;
英文:

I have a use-case where I need to generate an interface that inherits typing from another class with specific keys, and builds from there. I need to use this inherited-type, but also reduce data via JS into an instance of the inherited-type. Is there a way to only need to list off the keys once?

I am currently doing it like this:

interface IPrimaryType {
  key1: string;
  key2: string;
  key3: string;
  key4: string;
  key5: string;
  key6: string;
  key7: string;
}

interface ISecondaryType {
  thisDoesntMatter: string;
}

interface ITertiaryType {
  thisDoesntMatter: string;
}

interface IInheritedType extends Pick&lt;IPrimaryType, &#39;key1&#39; | &#39;key2&#39; | &#39;key3&#39; | &#39;key4&#39; | &#39;key5&#39;&gt; {
  secondaryData: ISecondaryType;
  tirtiaryData?: ITertiaryType | null;
}

const inheritedKeys = [&#39;key1&#39;, &#39;key2&#39;, &#39;key3&#39;, &#39;key4&#39;, &#39;key5&#39;];

const primaryObj = {
  key1: &#39;value1&#39;,
  key2: &#39;value2&#39;,
  key3: &#39;value3&#39;,
  key4: &#39;value4&#39;,
  key5: &#39;value5&#39;,
  key6: &#39;value6&#39;,
  key7: &#39;value7&#39;,
};
const secondaryData = { thisDoesntMatter: &#39;&#39; };
const tirtiaryData = { thisDoesntMatter: &#39;&#39; };

let inheritedObj = inheritedKeys.reduce(
  (acc, key: string) =&gt; ({ ...acc, [key]: (primaryObj as any)[key] }),
  {} as IInheritedType
);
inheritedObj.secondaryData = secondaryData;
inheritedObj.tirtiaryData = tirtiaryData;

答案1

得分: 1

以下是您要翻译的内容:

不能从诸如'key1' | 'key2' | 'key3' | 'key4' | 'key5'这样的类型派生值,因为类型系统在编译时被擦除。但您可以反过来从值派生类型。就像这样:

const inheritedKeys = [
  'key1',
  'key2',
  'key3',
  'key4',
  'key5',
] as const;

type InheritedKeys = typeof inheritedKeys[number];
// type InheritedKeys = "key1" | "key2" | "key3" | "key4" | "key5"

您必须使用const断言来要求编译器跟踪inheritedKeys初始化器的文字类型。否则,inheritedKeys将是string[]类型,个别元素如"key3"将被遗忘。

一旦您这样做,typeof类型查询运算符可以用于获取inheritedKeys变量的类型,并通过索引 number 来获取inheritedKeys数字索引处的值的类型,即元素类型。

因此,InheritedKeys是元素的文字类型的联合类型。您可以在IInheritedType的定义中使用InheritedKeys

interface IInheritedType extends Pick<IPrimaryType, InheritedKeys> {
  secondaryData: ISecondaryType;
  tertiaryData?: ITertiaryType | null;
}

Playground代码链接

英文:

You can't derive values like inheritedKeys from types like &#39;key1&#39; | &#39;key2&#39; | &#39;key3&#39; | &#39;key4&#39; | &#39;key5&#39;, since the type system is erased upon compilation. But you can do the reverse and derive types from values. Like this:

const inheritedKeys = [
&#39;key1&#39;,
&#39;key2&#39;,
&#39;key3&#39;,
&#39;key4&#39;,
&#39;key5&#39;,
] as const;
type InheritedKeys = typeof inheritedKeys[number];
// type InheritedKeys = &quot;key1&quot; | &quot;key2&quot; | &quot;key3&quot; | &quot;key4&quot; | &quot;key5&quot;

You have to use a const assertion to ask the compiler to keep track of the literal types of the initializer of inheritedKeys. Otherwise inheritedKeys would be of type string[] and the individual elements like &quot;key3&quot; would be forgotten.

Once you do that, the typeof type query operator can be used to get the type of the inheritedKeys variable, and by indexing into that with number you get the type of the values at numeric indices of inheritedKeys; that is, the element type.

And so InheritedKeys is the union of the literal types of the elements. And you can use InheritedKeys inside your definition of IInheritedType:

interface IInheritedType extends Pick&lt;IPrimaryType, InheritedKeys&gt; {
secondaryData: ISecondaryType;
tertiaryData?: ITertiaryType | null;
}

Playground link to code

huangapple
  • 本文由 发表于 2023年7月18日 02:37:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76707252.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定