Types
Concepts
Type assignability
We say that type A is assignable to type B if you can use a value of type A in all places where a value of type B is required. For example:
- assigning a value to a variable
- passing a function argument
- returning a value from a function that has an explicit return type
Optionality
consider that by default, null
and undefined
are part of the domain (Private) of virtually every type. That is, a string can be null
, an object property can be null
, and so on. When we enable strict null checking, we are removing null
from the domains of these types
strictNullChecks
forces you to explicitly distinguish between values that can benull
orundefined
and those that cannot be.
we could explicitly extend the type to once again include null
as part of the type's domain:
function bar(person: Person | null) {
But this may not be preferable. Instead we can use optional params (in functions and interfaces) to determine if something can be optional or not:
- also beneficial to use optional chaining to achieve the effect of optionality, (spec:)as opposed to type guards
interface Person {}
function hello(person?: Person) {}
interface Employee {
id: number;
name: string;
supervisorId?: number;
}
hello();
const employee: Employee = {
id: 1,
name: 'John',
};
/* * * * */
interface Person { hello(): void }
function sayHello(person: Person | undefined) {
person.hello(); // 🔴 Error!
// this is a type guard, and it allows the Typescript Type checker to
// deduce that the type of person inside the if statement is narrowed to just `Person`
if (person) {
person.hello(); // OK
}
}
Consider that a getUser
function might not return a user for a given ID. Therefore, we should set the return value of the function as a union between User and undefined.
getUser(id: number): User | undefined {
return this.users[id];
}
spec: If we don't want to specify a new type, we can just do this:
type TodoPrevious = Pick<Todo, "title" | "completed">
Here, "title" | "completed"
resolves to a type. We could have written it like this:
type ValueKeys = "tite" | "completed"
type TodoPrevious = Pick<Todo, ValueKeys>
after await
ing that action, the API call to the server is made along with the changelog objects. This should not block the client. if there is a connection to the server, the server will handle it and notify the client. If there is no connection to the server (or simply if there is an error), then the client will keep track of the changelog objects in its own database. Then, once connection to the server is reestablished, the client will send its changelog objects, as per the usual protocol.
Backlinks