Object literal with variable property is overly generic
xealot opened this issue · 6 comments
xealot commented
Code
interface BV {
A: string,
B: number,
}
type BVTemplate<K extends keyof BV> = {
[P in K]?: BV[P];
}
abstract class BaseBlock<T extends keyof BV> {
abstract readonly typeName: T;
value: BVTemplate<T>;
update(v: BV[T]) {
const updated: BVTemplate<T> = {
[this.typeName]: v,
}
// const updated: BVTemplate<T> = {};
// updated[this.typeName] = v;
this.value = updated;
}
}
Expected behavior:
typeName
is T
, but the type is incompatible with BVTemplate because the object literal declaration stores it as string
. string
is not compatible to T
.
Actual behavior:
I would hope this example could work. The commented string works perfectly, and in JS land those two things should be equivalent.
sylvanaar commented
The computed property doesn't take the union type - so it is widened to string.
Simplified Example
const a = {} as "FOO" | "BAR";
const o = {
[a]: true
};
// type of o is { [x: string]: boolean; }
sandersn commented
mhegazy commented
here is the sample using the unionize type:
class BaseBlock<T extends keyof BV> {
readonly typeName: T;
value: BVTemplate<T>;
update(v: BV[T]) {
type union = {[P in T]: {[Q in P]: typeof v } }[T];
const updated: BVTemplate<T> = {
[this.typeName]: v,
} as union;
this.value = updated;
}
}
typescript-bot commented
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.