如何创建类型的映射?

时间:2018-01-20 19:49:08

标签: typescript dictionary typing

例如,如果我有一些这样的代码来处理距离:

kilo(a: mm): m kilo(a: m): km unkilo(b: km): m unkilo(b: m): mm

我想扩展它以包含大多数SI前缀(微微,纳米,微米,毫米,(正常),千克,巨型等...)

这需要很多打字稿代码。

是否可以创建某种映射,以便我可以只有2行。

kilo (a: T): (lookup T in map) unkilo (b: T): (reverse lookup T in map)

1 个答案:

答案 0 :(得分:1)

我不确定你的类型是如何定义的,但我会假设它们是这样的:

type mm = number & { "**type**": "mm" }
type m = number & { "**type**": "m" }
type km = number & { "**type**": "km" }

这可能是表示它们的最轻量级方式:只是运行时的数字。或许你希望它们成为完整的物体。

重要的是,它们之间有一个共同属性(在这种情况下,"**type**")具有不同的字符串文字值("mm""m""km" )。然后你可以这样做:

interface KiloMap {
  mm: m
  m: km
}
interface UnkiloMap {
  m: mm
  km: m
}

表示您想要的映射。 TypeScript擅长将字符串文字映射到一般类型(实际上是接口),但不太擅长将一般类型映射到一般类型(至少没有像提议的extended typeof特性那样)。

最后,您可以编写函数类型:

function kilo<T extends (m | mm)>(a: T): KiloMap[T["**type**"]] {
  return a / 1000 as any;
}
function unkilo<T extends (km | m)>(a: T): UnkiloMap[T["**type**"]] {
  return a * 1000 as any;
}

并验证它们是否按预期工作:

const oneMeter = 1 as m;
const oneThousandthOfAKilometer = kilo(oneMeter); // km
const oneThousandMillimeters = unkilo(oneMeter); // mm

您可以根据需要添加新类型/映射/函数。希望有所帮助;祝你好运!