英文:
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<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;
答案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;
}
英文:
You can't derive values like inheritedKeys
from types like 'key1' | 'key2' | 'key3' | 'key4' | 'key5'
, since the type system is erased upon compilation. But you can do the reverse and derive types from values. Like this:
const inheritedKeys = [
'key1',
'key2',
'key3',
'key4',
'key5',
] as const;
type InheritedKeys = typeof inheritedKeys[number];
// type InheritedKeys = "key1" | "key2" | "key3" | "key4" | "key5"
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 "key3"
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<IPrimaryType, InheritedKeys> {
secondaryData: ISecondaryType;
tertiaryData?: ITertiaryType | null;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论