【发布时间】:2018-12-12 04:20:00
【问题描述】:
我一直在考虑如何为 daggy 之类的东西指定类型,您可以在其中指定数组中的属性名称列表并创建一些构造函数。
基本上,我认为想要这样的东西:
[A, B] with [X, Y] => { [A]: X, [B]: Y }
其中A 和B 是任意字符串常量类型,X 和Y 是任意类型。例如
['x', 'y'] with [string, number] => { x: string, y: number }
鉴于daggy 的目标用途,目标界面可能会以类似的方式结束
<K0 extends string, K1 extends string>(keys: [K0, K1])
=> <V0, V1>(v0: V0, v1: V1)
=> { [K0]: V0, [K1]: V1 }
我注意到有点接近但确实有效的一件事是 TS 似乎接受 [K in NS[number]: ... 和 [K in K0|K1] 为有效。以下按预期工作:
function point<
A extends string,
B extends string
>(names: [A, B]): { [K in A|B]: number };
function point(names: any[]): { [x: string]: number } {
return {
[names[0]]: 0,
[names[1]]: 0,
};
}
const p0 = point(['a', 'b']);
// :: { a: number, b: number }
但是,在这种情况下,您不能假定联合成员的迭代顺序,并且无法将这些成员与另一个联合的成员压缩在一起。
但如果我尝试直接使用K extends string 类型,像这样:
function createZip2Object<
K0 extends string,
K1 extends string
>(names: [K0, K1]): <V0, V1>(v0: V0, v1: V1) => { [K0]: V0, [K1]: V1 };
function createZip2Object(names: [string, string]): { [x: string]: any } {
return (...args) => ({
[names[0]]: args[0],
[names[1]]: args[1],
});
}
const point = createZip2Object(['x', 'y']);
const p0 = point(10, 945);
我收到了A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type. 和'K0' only refers to a type, but is being used as a value here. 的消息
即使是不尝试在内部函数中隐藏类型参数化的简单示例,也会出现此错误消息:
function boxValue<K extends string, V>(k: K, v: V): { [K]: V } {
return { [k]: v };
}
const bv = boxValue('v', 42);
// :: {}
这发生在 Typescript playground 和带有 Typescript 2.9.1 的 VSCode 中。
我知道我可以手动指定 daggy 的构造函数创建者返回的东西的类型,但我想知道是否有更通用的方法来做到这一点。
【问题讨论】:
标签: typescript