如何使用常量为对象定义通用接口?
How to define general interface for Object with constans?
在项目中我有一些带有字符串常量的对象。例如:
export const Elements: Constants {
DESCRIPTION: "DescriptionAutoField2",
FORMULA_CALC: "FormulaCalcAutoField1",
CHART_CODE: "ChartCodeAutoField1",
CHART_CODE_DESCRIPTION: "ChartDescriptionAutoField1",
};
export const ChartAttr: Constants = {
CHART: "Chart",
CHART_DESCRIPTION: "ChartDescr",
};
export const SliceLink: Constants = {
SLICE_CODE: "SliceCode",
SLICE_DESC: "SliceDesc",
SLICE_CALC: "SliceCalc",
};
我这样定义了接口,但在这种情况下无法在编译期间检查 Object kyes。
export interface Constants {
[key: string]: string;
}
我的问题是:如何定义通用接口"Constants"并根据定义的Object属性进行严格编译?是否可以避免 "enum"?
没有像 Constants
这样的单一具体类型可以同时匹配所有 Elements
、ChartAttr
和 SliceLink
,而 记住每个的确切键和值。相反,您可以表示匹配您的约束的 generic 类型,并使用辅助函数来确保值符合它,同时输出记住单个 key/value 类型的强类型值:
// helper function
const asConstants = <S extends string, T extends Record<keyof T, S>>(
c: T
): { readonly [K in keyof T]: T[K] } => c;
我假设您希望将常量属性标记为 readonly
并且每个值的类型应该是 string literal 而不仅仅是 string
.
现在您可以通过函数而不是注释来定义常量:
export const Elements = asConstants({
DESCRIPTION: "DescriptionAutoField2",
FORMULA_CALC: "FormulaCalcAutoField1",
CHART_CODE: "ChartCodeAutoField1",
CHART_CODE_DESCRIPTION: "ChartDescriptionAutoField1",
});
export const ChartAttr = asConstants({
CHART: "Chart",
CHART_DESCRIPTION: "ChartDescr",
});
export const SliceLink = asConstants({
SLICE_CODE: "SliceCode",
SLICE_DESC: "SliceDesc",
SLICE_CALC: "SliceCalc",
});
如果您使用 IDE 的 IntelliSense 检查 Elements
、ChartAttr
和 SliceLink
的类型,您会看到:
/*
const Elements: {
readonly DESCRIPTION: "DescriptionAutoField2";
readonly FORMULA_CALC: "FormulaCalcAutoField1";
readonly CHART_CODE: "ChartCodeAutoField1";
readonly CHART_CODE_DESCRIPTION: "ChartDescriptionAutoField1";
}
const ChartAttr: {
readonly CHART: "Chart";
readonly CHART_DESCRIPTION: "ChartDescr";
}
const SliceLink: {
readonly SLICE_CODE: "SliceCode";
readonly SLICE_DESC: "SliceDesc";
readonly SLICE_CALC: "SliceCalc";
}
*/
如果您尝试将错误的值传递给 asConstants()
,您会得到一个错误:
asConstants({
NOT_A_STRING: 1, // error! number not a string
})
好的,希望对您有所帮助。祝你好运!
在项目中我有一些带有字符串常量的对象。例如:
export const Elements: Constants {
DESCRIPTION: "DescriptionAutoField2",
FORMULA_CALC: "FormulaCalcAutoField1",
CHART_CODE: "ChartCodeAutoField1",
CHART_CODE_DESCRIPTION: "ChartDescriptionAutoField1",
};
export const ChartAttr: Constants = {
CHART: "Chart",
CHART_DESCRIPTION: "ChartDescr",
};
export const SliceLink: Constants = {
SLICE_CODE: "SliceCode",
SLICE_DESC: "SliceDesc",
SLICE_CALC: "SliceCalc",
};
我这样定义了接口,但在这种情况下无法在编译期间检查 Object kyes。
export interface Constants {
[key: string]: string;
}
我的问题是:如何定义通用接口"Constants"并根据定义的Object属性进行严格编译?是否可以避免 "enum"?
没有像 Constants
这样的单一具体类型可以同时匹配所有 Elements
、ChartAttr
和 SliceLink
,而 记住每个的确切键和值。相反,您可以表示匹配您的约束的 generic 类型,并使用辅助函数来确保值符合它,同时输出记住单个 key/value 类型的强类型值:
// helper function
const asConstants = <S extends string, T extends Record<keyof T, S>>(
c: T
): { readonly [K in keyof T]: T[K] } => c;
我假设您希望将常量属性标记为 readonly
并且每个值的类型应该是 string literal 而不仅仅是 string
.
现在您可以通过函数而不是注释来定义常量:
export const Elements = asConstants({
DESCRIPTION: "DescriptionAutoField2",
FORMULA_CALC: "FormulaCalcAutoField1",
CHART_CODE: "ChartCodeAutoField1",
CHART_CODE_DESCRIPTION: "ChartDescriptionAutoField1",
});
export const ChartAttr = asConstants({
CHART: "Chart",
CHART_DESCRIPTION: "ChartDescr",
});
export const SliceLink = asConstants({
SLICE_CODE: "SliceCode",
SLICE_DESC: "SliceDesc",
SLICE_CALC: "SliceCalc",
});
如果您使用 IDE 的 IntelliSense 检查 Elements
、ChartAttr
和 SliceLink
的类型,您会看到:
/*
const Elements: {
readonly DESCRIPTION: "DescriptionAutoField2";
readonly FORMULA_CALC: "FormulaCalcAutoField1";
readonly CHART_CODE: "ChartCodeAutoField1";
readonly CHART_CODE_DESCRIPTION: "ChartDescriptionAutoField1";
}
const ChartAttr: {
readonly CHART: "Chart";
readonly CHART_DESCRIPTION: "ChartDescr";
}
const SliceLink: {
readonly SLICE_CODE: "SliceCode";
readonly SLICE_DESC: "SliceDesc";
readonly SLICE_CALC: "SliceCalc";
}
*/
如果您尝试将错误的值传递给 asConstants()
,您会得到一个错误:
asConstants({
NOT_A_STRING: 1, // error! number not a string
})
好的,希望对您有所帮助。祝你好运!