Contemplating how to define types for a concept similar to daggy, where a list of property names in an array leads to the creation of constructors.
Thinking of something along these lines:
[A, B] with [X, Y] => { [A]: X, [B]: Y }
In this scenario, A
and B
represent arbitrary string-constant-types while X
and Y
are any types. For instance:
['x', 'y'] with [string, number] => { x: string, y: number }
Considering the target use case of daggy, the anticipated interface would likely resemble:
<K0 extends string, K1 extends string>(keys: [K0, K1])
=> <V0, V1>(v0: V0, v1: V1)
=> { [K0]: V0, [K1]: V1 }
An interesting observation is that TypeScript seems to accept [K in NS[number]: ...
and [K in K0|K1]
as valid constructs. The following snippet functions as intended:
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 }
However, there are limitations in terms of union member iteration order and merging with members of another union when opting for a direct K extends string
type:
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);
Encountering messages like
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
and 'K0' only refers to a type, but is being used as a value here.
.
Similar errors persist even in simpler examples not involving nested function parametrizations:
function boxValue<K extends string, V>(k: K, v: V): { [K]: V } {
return { [k]: v };
}
const bv = boxValue('v', 42);
// :: {}
These issues arise on the Typescript playground and in VSCode using Typescript 2.9.1.
While explicitly defining the returned type from daggy's constructor creators is an option, exploring a more comprehensive approach is desired.