在打字稿中映射分配类型

时间:2019-07-07 08:55:09

标签: typescript

我有以下类型声明:

export type Interval = '1m' | '3m' | '5m' | '15m' | '30m' | '1h' | '2h' | '4h' | '6h' | '8h' | '12h' | '1d' | '3d' | '1w' | '1M'

现在,我想创建一个类似于以下内容的类型映射器:

export type Mapping<T extends string, K> = { [k in keyof T]: K } // Doesn't work

这将允许执行以下操作:

export type IntervalValue = MappingOf<Interval, number>;

export const IntervalValue: MappingOf<Interval, number> = {
    '1m': 1000 * 60 * 1,
    '3m': 1000 * 60 * 3,
    '5m': 1000 * 60 * 5,
    '15m': 1000 * 60 * 15,
    '30m': 1000 * 60 * 30,
    '1h': 1000 * 60 * 60 * 1,
    '2h': 1000 * 60 * 60 * 2,
    '4h': 1000 * 60 * 60 * 4,
    '6h': 1000 * 60 * 60 * 6,
    '8h': 1000 * 60 * 60 * 8,
    '12h': 1000 * 60 * 60 * 12,
    '1d': 1000 * 60 * 60 * 24 * 1,
    '3d': 1000 * 60 * 60 * 24 * 3,
    '1w': 1000 * 60 * 60 * 24 * 7 * 1,
    '1M': 1000 * 60 * 60 * 24 * 31 * 1,
}

// Later I would do the following
const interval: Interval = '1m'
const intervalValue: IntervalValue = IntervalValue[interval]
// ... do something with intervalValue ...

不幸的是,当前MappingOf结果的实现是IntervalValue等于Interval类型本身……即现在:

IntervalValue is '1m' | '3m' | '5m' | '15m' | '30m' | '1h' | '2h' | '4h' | '6h' | '8h' | '12h' | '1d' | '3d' | '1w' | '1M'

2 个答案:

答案 0 :(得分:1)

您需要映射到T而不是keyof T

export type Intervals = '1m' | '3m' | '5m' | '15m' | '30m' | '1h' | '2h' | '4h' | '6h' | '8h' | '12h' | '1d' | '3d' | '1w' | '1M'

export type MappingOf<T extends string, K> = { [k in T]: K } 

export type IntervalValues = MappingOf<Intervals, number>;

export const IntervalValues: MappingOf<Intervals, number> = {
    '1m': 1000 * 60 * 1,
    '3m': 1000 * 60 * 3,
    '5m': 1000 * 60 * 5,
    '15m': 1000 * 60 * 15,
    '30m': 1000 * 60 * 30,
    '1h': 1000 * 60 * 60 * 1,
    '2h': 1000 * 60 * 60 * 2,
    '4h': 1000 * 60 * 60 * 4,
    '6h': 1000 * 60 * 60 * 6,
    '8h': 1000 * 60 * 60 * 8,
    '12h': 1000 * 60 * 60 * 12,
    '1d': 1000 * 60 * 60 * 24 * 1,
    '3d': 1000 * 60 * 60 * 24 * 3,
    '1w': 1000 * 60 * 60 * 24 * 7 * 1,
    '1M': 1000 * 60 * 60 * 24 * 31 * 1,
}

您的MappingOf类型等效于Record,我建议使用:

export type Intervals = '1m' | '3m' | '5m' | '15m' | '30m' | '1h' | '2h' | '4h' | '6h' | '8h' | '12h' | '1d' | '3d' | '1w' | '1M'



export const IntervalValues: Record<Intervals, number> = {
    '1m': 1000 * 60 * 1,
    '3m': 1000 * 60 * 3,
    '5m': 1000 * 60 * 5,
    '15m': 1000 * 60 * 15,
    '30m': 1000 * 60 * 30,
    '1h': 1000 * 60 * 60 * 1,
    '2h': 1000 * 60 * 60 * 2,
    '4h': 1000 * 60 * 60 * 4,
    '6h': 1000 * 60 * 60 * 6,
    '8h': 1000 * 60 * 60 * 8,
    '12h': 1000 * 60 * 60 * 12,
    '1d': 1000 * 60 * 60 * 24 * 1,
    '3d': 1000 * 60 * 60 * 24 * 3,
    '1w': 1000 * 60 * 60 * 24 * 7 * 1,
    '1M': 1000 * 60 * 60 * 24 * 31 * 1,
}

答案 1 :(得分:0)

好的,我在Generic mapping of types in typescript中找到了一个参考官方文档的答案:https://www.typescriptlang.org/docs/handbook/advanced-types.html#inference-from-mapped-types

结果类型如下:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}
type Record<K extends keyof any, T> = {
    [P in K]: T;
}