Skip to content

Why does { foo: T } not satisfy { [key:string]: T }? #6041

Closed
@MrHen

Description

@MrHen

Various libraries I use want to see dictionary "loops" that take some number of key/value pairs and operate on them. E.g.:

async.auto<any>({
   'foo': (cb) => getFoo(cb),
   'bar': ['foo', (cb, results) => getBar(results.foo)]
}, (err, results) => { ... });

The typings file for async likes to define helper dictionary types like this:

interface Dictionary<T> { [key: string]: T; }

Periodically, I need to create these key/value pairs conditionally and on the fly but the compiler yells at me if I try to send it in without explicitly typing my temporary object:

var block = {
    'foo': (cb) => getFoo(cb),
    'bar': ['foo', (cb, results) => getBar(results.foo)
}

if (flag) {
    block.foo = getOtherFoo(cb);
}

async.auto<any>(block, (err, results) => { ... });

block now technically satisfies the { [key: string]: T; } because it is an object with two keys, both strings. TypeScript will still yell at me for it, though, unless I explicit add a similar dictionary type to block. I, therefore, find myself putting this dictionary type all over the place just to satisfy what seems to be an arbitrary distinction between what is or is not a key:string.

This comes up enough that I find the type bloat irritating and it also makes it a requirement to only access block.foo as block['foo'].

Metadata

Metadata

Assignees

No one assigned

    Labels

    CommittedThe team has roadmapped this issueFixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions