Skip to content

Mapped types enumerating keys in string behave poorly #22509

Closed
@bterlson

Description

@bterlson

TypeScript Version: 2.8.0-dev20180308
Search Terms: mapped types
Code

type Thing = {
    [K in string]: K
};

var thing: Thing = new Proxy({}, {
    get(_, k) {
        return k;
    }
});

let res = thing.x; // res should be of type 'x', but is string

Playground Link

Here I expect string to behave as if it were the union of all possible string literal types. The present semantics are identical to a string indexer. IMO if we don't want map types K in string to do anything interesting, then the syntax should be an error and we should require people to write the indexer.

For what it's worth, ultimately I would love to type Allen's Apparatus for Method Extraction, roughly typed below:

type ExtractorThing = {
    [K in string]: <T>(base: T) => K extends keyof T ? T[K] : never;
}

var extract: ExtractorThing = new Proxy({}, {
    get(target, prop) {
        "use strict";
        return (base: any) => function(this: any, ...args: any[]) {
          return base[prop].apply(this || base, args); 
        }
    }
});

let obj = {
    x: 0,
    succ() {
        return ++this.x;
    },
    dec() {
        return --this.x;
    }
}

let succ = extract.succ(obj);
let dec = extract.dec(obj);

succ(); // 1
succ(); // 2
dec(); // 1
dec(); // 0

I would probably work towards putting a constraint on T such that you get a red squiggle if you pass an object without the proper method to extract, but hopefully this serves as a useful example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions