How can you create a mapped type that is a type of type?

Suppose I have an input that adheres to a certain type:

interface Person {
    name: string;
    age: number;
}

Now I want the function to accept an array of key-value pairs, for example:

function acceptsPersonProperties(tuple: Array<PersonTuple>) { ... }

// this should be fine:
acceptsPersonProperties([['name', 'Bob'], ['age', 42]]);

// this should give a compile-time error:
acceptsPersonProperties([['name', 2], ['age', 'Bob']]);

Of course, I can print this manually, for example:

type PersonTuple = ['name', string] | ['age', number];

But if a type (for example Person) is a template variable, how can a tuple be expressed as a matching type ?

function acceptsPropertiesOfT<T>(tuple: Array<MappedTypeHere<T>>) { ... }

To avoid the XY problem, the real use case is the following:

let request = api.get({
    url: 'folder/1/files',
    query: [
        ['fileid', 23],
        ['fileid', 47],
        ['fileid', 69]
    ]
});

which allows "/api/folder/1/files?fileid=23&fileid=47&fileid=69", but which I want to print, so it does not allow adding additional properties ( file_id) and checks the types (there is no line like fileid).

+6
source share
1

. Person.

, , , API:

interface Person {
  name: string;
  age: number;
}

function acceptsPersonProperties(tuple: Partial<Person>[]) { }

// this should be fine:
acceptsPersonProperties([{ name: 'Bob' }, { age: 42 }]);

// this should give a compile-time error:
acceptsPersonProperties([{ name: 2 }, { age: 'Bob' }]);
+4

Source: https://habr.com/ru/post/1016836/


All Articles