A record is a set of key-value pairs with the value having a given type (also called a struct, object, etc. depending on the context). In TypeScript, this is an example of a record:
const foo = { bar: 1, baz: "qux" };
Destructuring is an ergonomic feature where you can take the fields of a record and assign them to local variables. For example: // Equivalent to
// const bar = foo.bar;
// const baz = foo.baz;
const { bar, baz } = foo;
Besides ergonomics, destructuring can offer features like exhaustiveness-checking, to make sure that you used all of the fields of a record.A union type is a type which denotes that the value is one of two different types, indicated like this:
type Foo = number | string;
Sometimes, you have two different cases with the same type, and you want to distinguish between them. For example: // Not helpful -- we can't tell from the value
// whether it's supposed to be a username or an email.
type UsernameOrEmail = string | string;
To handle this case, you can use a discriminated union instead. These unions have a special value which unambiguously indicates which case is present: type UsernameOrEmail = { type: "username", value: string }
| { type: "email", value: string };
Sometimes, you have a discriminated union with different fields: type ApiRequest = { type: "message", subject: string, contents: string }
| { type: "view-posts", user_id: number };
Currently, TypeScript uses control-flow analysis to ensure that you're using the right kinds of fields depending on the discriminator value: const request: ApiRequest = getRequest();
if (request.type === "message") {
// Okay:
console.log("Subject is", request.subject);
// Rejected by compiler:
console.log("User ID is", request.user_id);
}
However, you can't combine this feature with destructuring: type Action = { kind: "A", payload: number }
| { kind: "B", payload: string };
const { kind, payload } = getAction();
if (kind === "B") {
// Not currently allowed:
payload.toUpperCase();
}
With this pull request, you can do the above. This can be convenient with patterns like reducers (see https://github.com/microsoft/TypeScript/issues/46143 for an example).