我可以在TypeScript中指定值类型但是仍然让TS推断出密钥类型吗?

时间:2017-09-07 16:04:28

标签: typescript

如果我在TypeScript中创建此常量:

const PARAMS = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

它将类型推断为{ green: {color: number}; black: { color: number }; white: { color: number }; }

但我从上下文中知道值的类型应为THREE.MeshBasicMaterialParameters。我可以使用索引类型声明这个:

const PARAMS: {[name: string]: THREE.MeshBasicMaterialParameters} = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

然后我失去了键的具体可能性(“绿色”,“黑色”或“白色”)。我可以通过写出我想要的完整类型来更精确地建模:

const PARAMS: {
  green: THREE.MeshBasicMaterialParameters,
  black: THREE.MeshBasicMaterialParameters,
  white: THREE.MeshBasicMaterialParameters
} = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

但这非常冗长和重复。

有没有办法以更简洁的方式获得我想要的类型?

2 个答案:

答案 0 :(得分:4)

您可以使用通用映射类型

来减少详细程度
a = float(-2)
b = float(-1)
n = ((a+b)/2)
print(n)

def equation(n):

    total = float((n - n**3 - 1))

    return total

i = 1

while i != 0:
    n = ((a + b) / 2)
    if (equation(n)) > 0.0:
        a = n
        i = equation(n)
        print(i)

    else:
        b = n
        i = equation(n)
        print(i)

但你还是要重复两次颜色名称。如果你想要打字键来推断键,你必须引入中间函数,在运行时完全没用。我不知道有任何其他方法可以使用打字稿来推断通用参数 - there is a proposal on github以允许扣除默认模板参数,但到目前为止还没有实现。

type ParamsType<Colors extends string> = {
    [c in Colors]: THREE.MeshBasicMaterialParameters;
}

const PARAMS: ParamsType<'green' | 'black' | 'white'> = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

<强>更新

正如@jcalz建议的那样,你可以通过将function inferColorKeys<Colors extends string>(params: ParamsType<Colors>): ParamsType<Colors> { return params; } const PARAMS = inferColorKeys({ green: {color: 0x007700}, black: {color: 0x000000}, white: {color: 0xffffff}, }); 放入一个带有显式泛型参数的函数并返回一个推断其泛型参数的函数,使其完全通用。它必须是两个函数,因为函数不能显式地显示某些通用参数,而是推断出一些参数。此外,它使用内置的inferKeys类型,定义为  Record

type Record<K extends string, V> = {[k in K]: V}

const inferKeys = <V>() => <K extends string>(x: Record<K,V>): Record<K,V> => x; const PARAMS = inferKeys<THREE.MeshBasicMaterialParameters>()({ green: {color: 0x007700}, black: {color: 0x000000}, white: {color: 0xffffff}, }); 的类型推断为

PARAMS

答案 1 :(得分:0)

这是你的选择吗?

const PARAMS = {
  green: {color: 0x007700} as THREE.MeshBasicMaterialParameters,
  black: {color: 0x000000} as THREE.MeshBasicMaterialParameters,
  white: {color: 0xffffff} as THREE.MeshBasicMaterialParameters,
};