【问题标题】:How to define general interface for Object with constans?如何用常量定义对象的通用接口?
【发布时间】:2020-03-01 20:19:15
【问题描述】:

在项目中,我有一些带有字符串常量的对象。例如:

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;
 }

我的问题是:如何定义通用接口“常量”并根据定义的对象属性进行严格编译?是否可以避免“枚举”?

【问题讨论】:

  • 使用枚举或常量枚举

标签: typescript typedef type-definition


【解决方案1】:

没有像Constants 这样的单一具体类型可以匹配所有ElementsChartAttrSliceLink,同时同时记住每个的确切键和值.相反,您可以表示一个与您的约束匹配的generic 类型,并使用一个辅助函数来确保值符合它,同时输出一个记住各个键/值类型的强类型值:

// 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 检查 ElementsChartAttrSliceLink 的类型,您会看到:

/*
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        
})

好的,希望对您有所帮助。祝你好运!

Link to code

【讨论】:

    猜你喜欢
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    相关资源
    最近更新 更多