Zev Spitz
Zev Spitz

Reputation: 15327

Type with members from a string array

Consider the following interface declaration:

interface Foo {
    bar(keys: string[], handler: (parameter: any) => void): void;
}

How can I represent that parameter of the handler is an object with members whose keys are in the keys array?

var x: Foo;
x.bar(['First', 'Second'], x => {
    console.log(x.First);
    console.log(x.Second);
});

Upvotes: 0

Views: 47

Answers (2)

Daniel Rosenwasser
Daniel Rosenwasser

Reputation: 23443

You want

  1. something that captures the string literals as a union of string literal types and
  2. something that can take that union of literal types and create an object out of it.

(1) can be done with a type parameter (i.e. a generic) constrained to string, and (2) can be done with a mapped type - and it just so happens that TypeScript ships a mapped type called Record<K, T> with it:

interface Foo {
    bar<K extends string>(keys: K[], handler: (parameter: Record<K, any>) => void): void;
}

var x: Foo;
x.bar(['First', 'Second'], x => {
    console.log(x.First);
    console.log(x.);
});

enter image description here

Keep in mind, however, that if someone passes in an empty array or something other than a string literal (e.g. a variable of type string), then you'll get no type safety. You'll be able to access any property on x.

You can get around the empty array case by adding a generic default of never to say "infer the empty union instead of string when given an empty array":

interface Foo {
    bar<K extends string = never>(keys: K[], handler: (parameter: Record<K, any>) => void): void;
}

Upvotes: 1

Saravana
Saravana

Reputation: 40584

You can use mapped types to map each of the item in the array as key:

interface Foo {
    bar<T extends string>(keys: T[], handler: (parameter: {
        [P in T]: any
    }) => void): void;
}

var x: Foo;
x.bar(['First', 'Second'], x => {
    console.log(x.First);
    console.log(x.Second);
    console.log(x.Third); //error
});

Upvotes: 0

Related Questions