Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Object literal with variable property is overly generic #21030

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.

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

No branches or pull requests

5 participants