Typescript
Typescript is Javascript with type safety.
E2E workflow efficiency with Typescript.
📄️ TsConfig
Compiler Options
📄️ Consuming APIs
Consuming APIs
📄️ Framework
Framework Code
📄️ Generics
Typescript Generics
📄️ tRPC
Replace REST with tRPC when using TypeScript.
📄️ Typescript Types
Typescript is Javascript with type safety.
📄️ Typescript
React and Typescript
TypeScript doesn't allow extra properties when passing literal objects to functions or assigning them directly to a variable with an explicit type.
Use Execute Program to get the fundamentals in your fingers.
Benefits
Code must be understandable and maintainable by other programmers, including programmers who join the team in the future and don't know the code's history.
Satisfying the type checker is like getting the code to work for the first time. It takes effort to make typing more understandable and maintainable.
- We tell the compiler what we believe about our code.
- The compiler analyzes those beliefs and checks for contradictions. Those contradictions are type errors.
- Stating beliefs in a more precise way, means more precise error messages in response.
- That makes debugging and maintenance easier
Best Practices
- Use Union Types instead of Enums
- Don't use default unless needed in Switch statements as it negates exhaustiveness checking
- Object literal may only specify known properties
Keyof with Typeof
An example where any modifications to the icons list will be handled by the compiler.
const icons = {
rightArrow: 'fake right arrow image',
leftArrow: 'fake left arrow image',
billing: 'fake billing image',
};
function Icon(props: { name: keyof typeof icons }) {
return icons[props.name];
}
Get type with typeof icons, which gives us {rightArrow: string, billing: string}.
Use keyof typeof icons to get the type 'rightArrow' | 'billing'
Pitfalls
- Using Any as a type
- Using As is dangerous
Assertion Functions
An assertion function throws an error unless some condition is true.
function assertNumber(n: unknown): asserts n is number {
if (typeof n !== 'number') {
throw new Error("Value wasn't a number: " + n);
}
}
Type guards and assertion functions are very closely related. The difference is in the scope of their type narrowing.
With a type guard the type is narrowed inside the code block. With an assertion function the type is narrowed for all code after the assertion call.
Write automated tests to be sure that your assertions functions are working as expected.
Extends vs Intersections
Sometimes intersections are the only tool for a particularly complex job. In those cases, you may find yourself reasoning through the type algebra to find out what's happening.
Generally favour extends to save from getting confusing errors.
Covariance vs Contravariance
The normal rule for assignability, where narrow types are assignable to wider types, is called covariance. But type compatibility is reversed for function parameter types. That's called contravariance.
In most strict static languages, function types are contravariant on the parameter types. Which means the following is OK.
type TakesLiteralString = (s: 'lastLoginDate') => string;
function takesString(s: string): string {
return s;
}
const testFunction: TakesLiteralString = takesString;
testFunction('lastLoginDate');
The testFunction variable only lets us pass the literal string 'lastLoginDate'. But the underlying takesString function can take 'lastLoginDate' or any other string.
By assigning an (s: string) => string function to an (s: 'lastLoginDate') => string variable, allowS a narrower set of arguments, which is safe.
Overloading
Overloading Functions and Options Objects can be useful in situations where there's a lot of code duplication.
type Comment = {
subject: string;
};
interface User {
id: number;
name: string;
}
interface UserWithComments extends User {
comments: Comment[];
}
function findUser(id: number): User;
function findUser(id: number, options: { withComments: true }): UserWithComments;
function findUser(id: number, options: { withComments?: boolean } = {}): User | UserWithComments {
const user = { id: 1, name: 'Amir' };
if (options.withComments) {
return { ...user, comments: [{ subject: "Ms. Fluff's 4th birthday" }] };
} else {
return user;
}
}
Related
Links
Education
Tools and Libraries