Skip to content

Object literal with variable property is overly generic #21030

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
xealot opened this issue Jan 5, 2018 · 6 comments
Closed

Object literal with variable property is overly generic #21030

xealot opened this issue Jan 5, 2018 · 6 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@xealot
Copy link

xealot commented Jan 5, 2018

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
Copy link

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; }

@mhegazy
Copy link
Contributor

mhegazy commented Jan 9, 2018

Should be addressed by #21070

@mhegazy mhegazy added the Bug A bug in TypeScript label Jan 9, 2018
@mhegazy mhegazy added this to the TypeScript 2.8 milestone Jan 9, 2018
@sandersn
Copy link
Member

sandersn commented Jan 9, 2018

After some discussion with @mhegazy, we decided that this issue is a job for the proposed Unionize type. It is not fixed by #21070 in any case.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 9, 2018

here is the sample using the unionize type:

class BaseBlock<T extends keyof BV> {
    readonly typeNameT;
    valueBVTemplate<T>;

    update(vBV[T]) {
       type union = {[P in T]{[Q in P]typeof v } }[T];

       const updatedBVTemplate<T> = {
           [this.typeName]v,
       } as union;
       this.value = updated;
    }
} 

@mhegazy
Copy link
Contributor

mhegazy commented Jan 9, 2018

more discussion in #18155

@mhegazy mhegazy added Design Limitation Constraints of the existing architecture prevent this from being fixed and removed Bug A bug in TypeScript labels Jan 9, 2018
@mhegazy mhegazy removed this from the TypeScript 2.8 milestone Jan 9, 2018
@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

5 participants