TYPE ⊆ SET منهج TypeScriptمن الجذور tsc --noEmit ✓
مخرجاتC

الورقة المرجعية Cheatsheet

للاسترجاع بعد الفهم لا للحفظ قبله


هذه ليست لتتعلّم منها؛ هي لتتذكّر بها ما اشتققته. كل سطرٍ هنا له "ليش" في إقليمٍ ما — إن لم تتذكّره، ارجع للإقليم لا للسطر.


الشبكة (الإقليم ٢)

النوعالمجموعةيُسنَد إليهيُسنَد منه
unknownكل القيم (القمّة)كل شيءلا شيء (إلا unknown)
never∅ (القاع)لا شيء (إلا never)كل شيء
anyليس مجموعة (ثقب)كل شيءكل شيء
void"تُجاهَل القيمة"undefined (وأي عائدٍ يُهمَل)

قاعدة: استبدل كل any بـ unknown، ثم ضيّق.

جبر المجموعات (الإقليم ٣)

typescript
A | B // اتحاد: قيمة في A أو B؛ عمليات A ∩ B فقط A & B // تقاطع: قيمة في A و B؛ كائنات أغنى string & number // = never "a" | "b" | "c" // مجموعة محدودة بالتعداد let x = 5 // → number (widening) const x = 5 // → 5 x = "n" as const // → "n" (أضيق + readonly)

التضييق (الإقليم ٤)

typescript
typeof x === "string" | "number" | "boolean" | "object" | ... if (x) {} // يطرح القيم الكاذبة x === "literal" // يثبت/يطرح حرفية "key" in obj // وجود خاصية x instanceof Class // عضوية صنف Array.isArray(x) // مصفوفة x == null // null و undefined معاً // discriminated union + exhaustiveness: switch (s.kind) { case "a": ... default: const _: never = s; // حارس الشمول } function isT(x: unknown): x is T { ... } // type predicate function assertT(x: unknown): asserts x is T { ... }

الكائنات (الإقليم ٥)

typescript
{ x: number; y?: number } // y اختيارية = number | undefined { readonly x: number } // قيدٌ وقت الترجمة فقط (يُمحى!) { [k: string]: number } // index signature (قاموس) // excess property check: يضرب فقط على الكائنات الحرفية الطازجة

التباين (الإقليم ٦)

المعاملات → contravariant (الاستهلاك يقلب ⊆) الإرجاع → covariant (الإنتاج يحفظ ⊆) المصفوفات → covariant عمداً = ثقب (Dog[] حيث Animal[]) () => void يقبل أي عائد (covariance + مستهلك أعمى)

Generics (الإقليم ٧)

typescript
function id<T>(x: T): T { return x; } <T extends { length: number }> // قيد = T ⊆ C <T, K extends keyof T>(o: T, k: K): T[K] // keyof + indexed access type Box<T> = { value: T }; type Pair<A, B = A> = { first: A; second: B }; // افتراضي

البرمجة على الأنواع (الإقليم ٨)

typescript
T extends U ? X : Y // if (يوزّع على الاتحاد إن كان T عارياً) [T] extends [U] ? X : Y // تعطيل التوزيع T extends (...a: any[]) => infer R ? R : never // استخراج (infer) T extends (infer E)[] ? E : never T extends Promise<infer V> ? V : T { [K in keyof T]: T[K] } // mapped (حلقة) { readonly [K in keyof T]?: T[K] } // مع مُعدِّلات { -readonly [K in keyof T]-?: T[K] } // نزع المُعدِّلات { [K in keyof T as `get${Capitalize<string & K>}`]: ... } // key remap + template type Reverse<T extends any[]> = T extends [infer H, ...infer R] ? [...Reverse<R>, H] : []; // عودية

أدوات قياسية جاهزة (كلها مبنيّة ممّا سبق — اقرأ مصدرها): Partial<T>, Required<T>, Readonly<T>, Pick<T,K>, Omit<T,K>, Record<K,V>, Exclude<T,U>, Extract<T,U>, NonNullable<T>, ReturnType<F>, Parameters<F>, Awaited<T>.

الحواف ونقاط الثقة (الإقليم ٩)

typescript
x as T // ادّعاء بلا فحص (ليس cast — صفر أثر وقت التشغيل) x! // "ليست null" بلا فحص JSON.parse(s) // any → ادّعاء النوع كذبةٌ غير مفحوصة arr[i] // قد يكون undefined (فعّل noUncheckedIndexedAccess) // عبور الجدار الصحيح: const data: unknown = JSON.parse(raw); if (!isUser(data)) throw new Error("invalid"); data.id; // مفحوصٌ الآن // استعادة الاسمية: type Brand<T, B> = T & { readonly __brand: B }; type UserId = Brand<number, "UserId">;

tsconfig — الأعلام التي تهمّ

tsconfig.json
{ "compilerOptions": { "strict": true, // إلزامي — يشمل strictNullChecks و strictFunctionTypes "noUncheckedIndexedAccess": true, // يغلق ثقب الفهرسة (خارج strict) "noImplicitAny": true, // ضمن strict "exactOptionalPropertyTypes": true // صرامة أعلى لـ ? } }

الأوامر

bash
tsc --noEmit # افحص بلا إخراج JS tsc --watch # افحص مستمراً # أو جرّب فوراً: https://www.typescriptlang.org/play

مبدأ

القاعدة الذهبية فوق كل ما سبق: حين يرفض المترجم، اسأل "أي ادّعاءٍ رياضي يقول إنه كاذب؟" لا "كيف أُسكِته؟". المترجم يبرهن؛ افهم البرهان.

منهج TypeScript — من الجذور · نظرية مجموعات + مُبرهِن نظريات النوع = مجموعة