sandra-larsson
Educator Fullstack Developer Javascript at Chas Academy
FJS26 · V50 · TISDAG
Typer som fungerar för många typer, och typer som skapas ur andra typer.
Chas Academy · Tisdag 8 december 2026
VARFÖR GENERICS?
Vi vill ha första elementet i en lista. Vilken lista som helst.
const firstNumber = (items: number[]) => items[0]; const firstString = (items: string[]) => items[0]; // och så vidare...
const first = (items: any[]) => items[0]; const x = first([10, 20]); // x: any x.toUpperCase(); // inget fel, kraschar
VARFÖR GENERICS?
GENERICS
const first = <T>(items: readonly T[]) : T | undefined => items[0];
first([10, 20, 30]); // T = number, ger number | undefined first(['Ada', 'Grace']); // T = string first<string>([]); // T skriven för hand
GENERICS
Vinkelparenteserna har funnits där hela tiden.
const prices: Array<number> = [39, 49]; // samma som number[]
const stock =
new Map<string, number>();
stock.set('kaffe', 12);const load = async ()
: Promise<string> => {
return 'klart';
};GENERICS
En typ kan också ha typparametrar.
type Pair<A, B> = {
first: A;
second: B;
};const price: Pair<string, number> = {
first: 'kaffe',
second: 39,
};EXTENDS
const longest = <T>(a: T, b: T) => a.length >= b.length ? a : b; // Fel: Property 'length' does // not exist on type 'T'
const longest = <T extends { length: number }>(
a: T,
b: T,
): T => (a.length >= b.length ? a : b);
longest('kaffe', 'te'); // 'kaffe'
longest([1, 2], [1, 2, 3]);
longest(10, 20); // FelEXTENDS
type HasId = { id: string };
const findById = <T extends HasId>(
items: readonly T[],
id: string,
): T | undefined =>
items.find((item) => item.id === id);findById(products, 'bulle')?.price; findById(users, 'u1')?.email; // TypeScript vet att det är en // produkt respektive en användare
EXTENDS
const findById = ( items: readonly HasId[], id: string, ): HasId | undefined => ...; findById(products, 'bulle')?.price; // Fel: Property 'price' does not // exist on type 'HasId'
Utan T kommer bara HasId ut, och resten av produkten är borta för TypeScript. Med T följer hela typen med, och extends garanterar bara att id finns.
Använd en generic när typen ut beror på typen in. Annars räcker en vanlig typ.
Typer som skapas ur andra typer.
UTILITY TYPES
type Product = {
id: string;
name: string;
price: number;
category: 'dryck' | 'bröd' | 'mat';
description: string;
};En uppdatering har bara några fält. Ett kort visar bara namn och pris. En ny produkt har inget id än. Ska vi skriva fyra typer för hand?
UTILITY TYPES
Alla fält valfria.
const update = (
p: Product,
changes: Partial<Product>,
): Product =>
({ ...p, ...changes });Bara några fält.
type ProductCard = Pick< Product, 'name' | 'price' >;
Allt utom några fält.
type NewProduct = Omit<Product, 'id'>;
UTILITY TYPES
type Category = Product['category'];
const labels: Record<Category, string> = {
dryck: 'Drycker',
bröd: 'Bröd och bullar',
mat: 'Mat',
};
// saknas en kategori blir det felconst frozen: Readonly<Product> = latte; frozen.price = 10; // Fel: Cannot assign to 'price' // because it is a read-only property
UTILITY TYPES
type ProductUpdate = Partial<Omit<Product, 'id'>>;
Ta Product, ta bort id, och gör resten valfritt. Ändras Product följer ProductUpdate med.
Övning
I src/2-utility-types.ts: skriv updateProduct, ProductCard, NewProduct med createProduct, categoryLabels och ProductUpdate. Ta sedan bort en nyckel ur categoryLabels och läs felet.
15 min
Du kan skapa nya typer ur en befintlig typ i stället för att skriva dem för hand.
MODULER
export type Category = 'dryck' | 'bröd' | 'mat';
export type Product = {
id: string;
name: string;
price: number;
category: Category;
};import type { Product } from './types';
import { products } from './products';
const cheap: Product[] = products
.filter((p) => p.price < 40);MODULER
Importerar bara typen. Raden finns inte kvar i den byggda JavaScript-koden, eftersom typer inte finns när koden körs.
Med den i tsconfig.json är det ett fel att importera en typ utan type. Då ser man direkt vad som är typ och vad som är kod.
import { Product } from './types';
// Fel: 'Product' is a type and must
// be imported using a type-only importTyperna finns bara medan du skriver koden. När den körs finns bara JavaScript kvar.
EFTER PASSET
npm run check.unknown, type guards och Zod.By sandra-larsson