Let's assume I have an input which adheres to a defined type:
interface Person {
name: string;
age: number;
}
Now, I want a function to accept an array of key-value pairs, e.g.:
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 type this manually, e.g.:
type PersonTuple = ['name', string] | ['age', number];
But if type (e.g. Person
) is a template variable, how can the tuple be expressed as a mapped type?
function acceptsPropertiesOfT<T>(tuple: Array<MappedTypeHere<T>>) { ... }
To avoid an X-Y-Problem, the real use case is this:
let request = api.get({
url: 'folder/1/files',
query: [
['fileid', 23],
['fileid', 47],
['fileid', 69]
]
});
which resolves to "/api/folder/1/files?fileid=23&fileid=47&fileid=69"
, but which I want to type, so it does not allow extra properties (file_id
) and checks types (no string as fileid
).
To define a Tuple type, we use syntax similar to Javascript array syntax but instead of specifying the values, we specify the type in each index location, as shown below. type PersonNameAge = [string, number];
A mapped type is a generic type which uses a union of PropertyKey s (frequently created via a keyof ) to iterate through keys to create a type: type OptionsFlags < Type > = { [ Property in keyof Type ]: boolean; };
Use Map type and new keyword to create a map in TypeScript. let myMap = new Map<string, number>(); To create a Map with initial key-value pairs, pass the key-value pairs as an array to the Map constructor.
Tuple. Tuples are used to store multiple items in a single variable. Tuple is one of 4 built-in data types in Python used to store collections of data, the other 3 are List, Set, and Dictionary, all with different qualities and usage. A tuple is a collection which is ordered and unchangeable.
You can't do it with tuple types. The right side of the tuple will always get generalized to a union of all possible values in Person
.
You can, however, make it work if you change your API slightly:
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' }]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With