Typescript 映射类型 - 枚举值作为键,接口对应的值作为值
Typescript mapped types - enum value as key, and interface's corresponding value as value
我有一组首选项,定义为字符串枚举:
export enum PreferenceTypes {
language = "language",
unit = "unit",
}
然后我可以创建一个界面来定义预期对象的形状。键将是枚举的值:
export type UnitTypes = "µg/m3" | "ppm" | "ppb";
export type LanguageTypes = "English" | "Spanish";
export interface PreferenceOptions {
[PreferenceTypes.language]: {
name: string;
value: LanguageTypes;
}[];
[PreferenceTypes.unit]: {
name: string;
value: UnitTypes;
}[];
}
现在我想创建一个基于用户语言环境的默认首选项对象。我希望这个新对象的键是本地的,我希望值是对象。每个对象都应该有 PreferenceTypes
类型的键,值必须是 PreferenceOptions
中对应 PreferenceType
类型的 value
类型。我正在尝试构建这样的类型约束,但我遇到了困难:
PreferenceByLocale: {
[key: string]: { [key in PreferenceTypes]?: string };
} = {
/** Defaults for UK users */
en: {
language: "English",
unit: "µg/m3",
},
/** Defaults for Spain users */
es: {
language: "Spanish",
unit: "µg/m3",
},
/** Defaults for US users */
us: {
language: "English",
unit: "ppm",
},
};
我不知道如何说这些对象中的每一个的值实际上应该是 { [T extends key in PreferenceTypes]?: PreferenceOptions[T]['value'] }
- 这给了我 TS 错误。我不确定我正在尝试做的事情是否可行,或者我是否正在考虑我的打字。例如,如果我这样写,我应该能够得到一个错误:
PreferenceByLocale: {
[key: string]: { [key in PreferenceTypes]?: string };
} = {
/** Defaults for mars users */
mrs: {
// I want this to error, as "Martian" does not exist on LanguageTypes
language: "Martian",
unit: "µg/m3",
},
}
这样的事情可能吗?
你的错误是:在定义PreferenceOptions时,每个属性的值都是一个数组。仔细检查下面的代码:
export interface PreferenceOptions {
[PreferenceTypes.language]: {
name: string;
value: LanguageTypes;
}[];
[PreferenceTypes.unit]: {
name: string;
value: UnitTypes;
}[];
}
您需要知道,在 TypeScript 中,如果您将 []
添加到值的末尾,它会将其定义为数组。所以下面两段代码给出了相同的结果:
let names : Array<string> = [];
let names : string[] = [];
所以您所要做的就是更改 PreferenceOptions 如下:
export interface PreferenceOptions {
[PreferenceTypes.language]: {
name: string;
value: LanguageTypes;
};
[PreferenceTypes.unit]: {
name: string;
value: UnitTypes;
};
}
现在试试这个:
const PreferenceByLocale: {
[key: string]: { [key in PreferenceTypes]?: string };
} = {
/** Defaults for UK users */
en: {
language: "English",
unit: "µg/m3",
},
/** Defaults for Spain users */
es: {
language: "Spanish",
unit: "µg/m3",
},
/** Defaults for US users */
us: {
language: "English",
unit: "ppm",
},
};
console.log(PreferenceByLocale)
将给出以下结果:
{
en: { language: 'English', unit: 'µg/m3' },
es: { language: 'Spanish', unit: 'µg/m3' },
us: { language: 'English', unit: 'ppm' }
}
好的,我想我现在更清楚你想做什么了。我做了这样的修改。
export enum PreferenceTypes {
language = "language",
unit = "unit",
}
export type UnitTypes = "µg/m3" | "ppm" | "ppb";
export type LanguageTypes = "English" | "Spanish";
export interface PreferenceOptions {
[PreferenceTypes.language]: LanguageTypes;
[PreferenceTypes.unit]: UnitTypes;
}
export interface PreferenceByLocale {
[key : string]: PreferenceOptions;
}
const PreferenceByLocale: PreferenceByLocale = {
/** Defaults for UK users */
en: {
language: "English",
unit: "µg/m3",
},
/** Defaults for Spain users */
es: {
language: "Spanish",
unit: "µg/m3",
},
/** Defaults for US users */
us: {
language: "English",
unit: "ppm",
},
mrs: {
language: "Unkown",
unit: "sxsx"
}
};
console.log(PreferenceByLocale);
现在它为夫人给出以下错误:
我想这就是你想要做的。如果那是你想做的并且代码很难理解,我可以解释。
我有一组首选项,定义为字符串枚举:
export enum PreferenceTypes {
language = "language",
unit = "unit",
}
然后我可以创建一个界面来定义预期对象的形状。键将是枚举的值:
export type UnitTypes = "µg/m3" | "ppm" | "ppb";
export type LanguageTypes = "English" | "Spanish";
export interface PreferenceOptions {
[PreferenceTypes.language]: {
name: string;
value: LanguageTypes;
}[];
[PreferenceTypes.unit]: {
name: string;
value: UnitTypes;
}[];
}
现在我想创建一个基于用户语言环境的默认首选项对象。我希望这个新对象的键是本地的,我希望值是对象。每个对象都应该有 PreferenceTypes
类型的键,值必须是 PreferenceOptions
中对应 PreferenceType
类型的 value
类型。我正在尝试构建这样的类型约束,但我遇到了困难:
PreferenceByLocale: {
[key: string]: { [key in PreferenceTypes]?: string };
} = {
/** Defaults for UK users */
en: {
language: "English",
unit: "µg/m3",
},
/** Defaults for Spain users */
es: {
language: "Spanish",
unit: "µg/m3",
},
/** Defaults for US users */
us: {
language: "English",
unit: "ppm",
},
};
我不知道如何说这些对象中的每一个的值实际上应该是 { [T extends key in PreferenceTypes]?: PreferenceOptions[T]['value'] }
- 这给了我 TS 错误。我不确定我正在尝试做的事情是否可行,或者我是否正在考虑我的打字。例如,如果我这样写,我应该能够得到一个错误:
PreferenceByLocale: {
[key: string]: { [key in PreferenceTypes]?: string };
} = {
/** Defaults for mars users */
mrs: {
// I want this to error, as "Martian" does not exist on LanguageTypes
language: "Martian",
unit: "µg/m3",
},
}
这样的事情可能吗?
你的错误是:在定义PreferenceOptions时,每个属性的值都是一个数组。仔细检查下面的代码:
export interface PreferenceOptions {
[PreferenceTypes.language]: {
name: string;
value: LanguageTypes;
}[];
[PreferenceTypes.unit]: {
name: string;
value: UnitTypes;
}[];
}
您需要知道,在 TypeScript 中,如果您将 []
添加到值的末尾,它会将其定义为数组。所以下面两段代码给出了相同的结果:
let names : Array<string> = [];
let names : string[] = [];
所以您所要做的就是更改 PreferenceOptions 如下:
export interface PreferenceOptions {
[PreferenceTypes.language]: {
name: string;
value: LanguageTypes;
};
[PreferenceTypes.unit]: {
name: string;
value: UnitTypes;
};
}
现在试试这个:
const PreferenceByLocale: {
[key: string]: { [key in PreferenceTypes]?: string };
} = {
/** Defaults for UK users */
en: {
language: "English",
unit: "µg/m3",
},
/** Defaults for Spain users */
es: {
language: "Spanish",
unit: "µg/m3",
},
/** Defaults for US users */
us: {
language: "English",
unit: "ppm",
},
};
console.log(PreferenceByLocale)
将给出以下结果:
{
en: { language: 'English', unit: 'µg/m3' },
es: { language: 'Spanish', unit: 'µg/m3' },
us: { language: 'English', unit: 'ppm' }
}
好的,我想我现在更清楚你想做什么了。我做了这样的修改。
export enum PreferenceTypes {
language = "language",
unit = "unit",
}
export type UnitTypes = "µg/m3" | "ppm" | "ppb";
export type LanguageTypes = "English" | "Spanish";
export interface PreferenceOptions {
[PreferenceTypes.language]: LanguageTypes;
[PreferenceTypes.unit]: UnitTypes;
}
export interface PreferenceByLocale {
[key : string]: PreferenceOptions;
}
const PreferenceByLocale: PreferenceByLocale = {
/** Defaults for UK users */
en: {
language: "English",
unit: "µg/m3",
},
/** Defaults for Spain users */
es: {
language: "Spanish",
unit: "µg/m3",
},
/** Defaults for US users */
us: {
language: "English",
unit: "ppm",
},
mrs: {
language: "Unkown",
unit: "sxsx"
}
};
console.log(PreferenceByLocale);
现在它为夫人给出以下错误:
我想这就是你想要做的。如果那是你想做的并且代码很难理解,我可以解释。