typescript - 如何正确索引和修改通用部分
问题描述
这是我的第一个泛型类型函数,如果有人能帮助我理解 Partials 和一般 TS 行为,我将不胜感激。
目的是什么:
1. 传递类型的对象<T>
2. 修改它并返回类型的预期对象<U>
下面的示例带有代码沙箱中的实时警告: https ://codesandbox.io/s/small-wood-yq14e
PS:我对如何在 TS 最佳实践中实际处理整个事情的新想法持开放态度:-)
export type ObjectWithStrings = { [index: string]: string }
// some demo data
const CONTAINER_NUTRIENTS_NAMES_ORDER: ObjectWithStrings = {}
const LIPIDS_NUTRIENTS_NAMES_ORDER: ObjectWithStrings = {}
const NUTRIENTS_MODEL_MAP: ObjectWithStrings = {}
function _sortNutrientsModel<T> (nutrientsModel: T) {
const sortedNutrientsModel: Partial<T> = {}
for (const sectionName in CONTAINER_NUTRIENTS_NAMES_ORDER) {
if (CONTAINER_NUTRIENTS_NAMES_ORDER.hasOwnProperty(sectionName)) {
/*
sortedNutrientsModel[sectionName]:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Partial<T>'.
No index signature with a parameter of type 'string' was found on type 'Partial<T>'.ts(7053)
nutrientsModel[sectionName]:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'.
No index signature with a parameter of type 'string' was found on type 'unknown'.ts(7053) */
sortedNutrientsModel[sectionName] = nutrientsModel[sectionName]
}
}
for (const sectionName in LIPIDS_NUTRIENTS_NAMES_ORDER) {
/*
Property 'lipids' does not exist on type 'T'.ts(2339) */
if (LIPIDS_NUTRIENTS_NAMES_ORDER.hasOwnProperty(sectionName) && sortedNutrientsModel.lipids.sections[sectionName]) {
sortedNutrientsModel.lipids.sections[sectionName] = nutrientsModel.lipids.sections[sectionName]
}
}
return sortedNutrientsModel
}
export function createNutrientsModel<T extends object, U> (nutrients: T) {
const nutrientsModel: Partial<U> = {}
for (const nutrientName in nutrients) {
if (nutrients.hasOwnProperty(nutrientName)) {
const nutrientLocation = NUTRIENTS_MODEL_MAP[nutrientName]
if (typeof nutrientLocation === `string`) {
const nutrientValues = nutrients[nutrientName]
switch (nutrientLocation.length) {
case 0: /* Container nutrient section */
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
if (typeof nutrientsModel[nutrientName] === `undefined`) {
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
nutrientsModel[nutrientName] = {}
}
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
nutrientsModel[nutrientName].values = nutrientValues
break
default: /* Nutrient section */
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
if (nutrientsModel[nutrientLocation] === `undefined`) {
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
nutrientsModel[nutrientLocation] = {}
}
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
if (typeof nutrientsModel[nutrientLocation].sections === `undefined`) {
nutrientsModel[nutrientLocation].sections = {}
}
/*
Type 'Extract<keyof T, string>' cannot be used to index type 'Partial<U>'.ts(2536) */
nutrientsModel[nutrientLocation].sections[nutrientName] = {
values: nutrientValues
}
}
}
}
}
return _sortNutrientsModel(nutrientsModel) as U
}
更新NutrientsType示例
interface BalanceModelSection {
DRI: {
AI: number,
AMDR: BalanceModelAMDR
EAR: number,
RDA: number,
UL: number,
unit: string
[index: string]: string | number | BalanceModelAMDR
}
}
interface BalanceRecordSectionValues {
converted: {
quantity: number
recommended: number
unit: string
}
quantity: number
percentage: string
}
interface BalanceRecordSection extends
BalanceRecordSectionValues,
BalanceModelSection {}
interface BalanceRecordNutrients {
[index: string]: BalanceRecordSection | BalanceRecordProgressSection
energy: BalanceRecordSection
}
解决方案
推荐阅读
- azure - 在用户之间分摊启用 Azure 语音的机器人的成本
- javascript - 如何做 z-index 的反向功能
- xamarin - 如何获得网络速度,在 xamarin iOS 中是快还是慢?
- python - 我怎么知道在 Android 上运行 selenium
- javascript - 如何在使用 vue.js 提交表单之前显示图像预览?
- c# - 比较两个日期时,并非所有代码路径都返回一个值?
- python - 熊猫数据框到列表字典
- excel - 如何使用 VBA 动态更新散点图系列?
- api - Unity3d Probuilder 脚本。如何在代码中应用纹理?
- execution-time - ProcessPoolExecutor 在 windows 上比在 mac 上花费更多时间