Developer frontend od ponad 10 lat
Ponad 5 lat w CD Projekt
Od niecałego roku w T-Mobile
Skupiony przede wszystkim
nad integracjami z CMS oraz DX
JS Developer Experience
const message = "Hello World!";
// ...
message();
TypeError: message is not a function
const message = "Hello World!";
Podstawy
let a: never;
let b: unknown;
let c: any = "Jeż"
Prostsze podstawy
let forename: string = "Adam";
let dev: boolean = true;
let age: number = 27;
type Question1 = string | number;
type Question2 = string & number;
type Question3 = String | Number;
type Question4 = String & Number;
type Id = number | string;
type TUser = {
id: Id;
name: string;
}
interface IUser {
id: Id;
name: string;
}
type UUID = typeof import("uuid").v4;
type TExtraUser = TUser & {
id: UUID;
surname: string;
}
interface IExtraUser extends IUser {
// id: UUID;
surname: string;
}
const id = "1234" as unknown as UUID;
type TAdminUser = Omit<TUser, "id"> & {
id: UUID;
keys: "adminKeys";
}
interface IAdminUser extends Omit<IUser, "id"> {
id: UUID;
keys: "adminKeys";
}
type User = TUser | IUser;
type AdminUser = TAdminUser | IAdminUser;
const isAdminUser =
(user: User | AdminUser): user is AdminUser => true;
// Funkcje
const randomInt = (max: number = 100) =>
Math.floor(Math.random() * max);
randomInt();
function randomIntBetween(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
// Generics
function arrayLength<T>(arg: T[]) { return arg.length; }
const len = arrayLength([1, 1, 2, 3, 5, 8]);
const len2 = arrayLength(["a", "b"]);
// Template literals
type AdminKeys = "adminKeys";
type Keys<T> = `Keys`;
type UserType = "regular" | "extra" | "admin";
type UnknownUser = { keys: Keys<UserType> } & { [k: string]: unknown };
const getUser = (type: UserType) => ({} satisfies UnknownUser);
// Satisfies
type PaletteKey = "red" | "green" | "blue";
type RGB = [number, number, number];
type Palette = { [key in PaletteKey]?: string | RGB };
const paletteNo = { reed: 12 } as Palette;
const palette1: Palette = { red: [255, 0, 0] };
const palette2 = { red: [255, 0, 0] } satisfies Palette;
paletteNo.red;
palette1.red;
palette2.red;
// Conditional Types & infer
// type UnknownUser = { [key: string]: unknown };
// const getUser = () => ({} satisfies UnknownUser);
type Test<T extends boolean> = T extends true ? 1 : 0;
// RetrunType -> https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype
type Return<T extends (...args: any) => any> =
T extends (...args: any) => infer R ? R : any;
type GetUserType = Return<typeof getUser>
const promise = Promise.resolve("hiddenMessage" as const);
type Await<T> = T extends PromiseLike<infer U> ? U : T;
type Await2<T> = T extends { then: (fn: (v: any) => any) => any } ? any : T;
Kiedy pisać co zwracam z funkcji?
a) Na początku
function getData(data: unknown): Promise<string> { /*...*/ }
b) Nie pisać, tylko zwracać
function getData(data: unknown) { /*...*/ return Promise.resolve("data") }
type TrimLeft<T extends string> =
T extends ` ${infer Rest}` ? TrimLeft<Rest> : T;
type OptimizedTitle = TrimLeft<" Greatest">
Stack Overflow & Google & TS Handbook = never
- Lepszy DX
- Linter, a nie język
- Mniejsza ilość błędów
- Wsparcie w bibliotekach
Niech Ts Cię nie ogranicza!
- Interfejsy
- Zod / ArkType
- ts-reset
- pretty-ts-errors
Źródła
Inspiracje
- https://www.youtube.com/@jherr
- https://www.youtube.com/@t3dotgg
- https://www.youtube.com/@mattpocockuk
Dziękuję ❤️
Jeśli spodobało Ci się - kliknij dużo gwiazdek 😉