面向函数式程序员的 TypeScript

TypeScript 的诞生是为了将传统的面向对象类型引入 JavaScript,以便 Microsoft 的程序员可以将传统的面向对象程序引入 Web。随着它的发展,TypeScript 的类型系统已经发展到可以为原生 JavaScript 编写的代码建模。由此产生的系统功能强大、有趣且混乱。

本简介专为想要学习 TypeScript 的在职 Haskell 或 ML 程序员而设计。它描述了 TypeScript 的类型系统与 Haskell 的类型系统有何不同。它还描述了 TypeScript 类型系统的独特功能,这些功能源自其对 JavaScript 代码的建模。

本简介不包括面向对象编程。实际上,TypeScript 中的面向对象程序类似于其他具有 OO 特性的流行语言中的程序。

先决条件

在本介绍中,我假设您了解以下内容:

  • 如何用 JavaScript 编程,好的部分。
  • C 语言后裔的类型语法。

lWdc21HOYoQeezEBMeJS6hYkjBJ90aSSK/P6/3IIiSCblgMh1F9IFLzFYEVKT8HCbSIUhTBizzVC1EyDGn4N6UFELr6qcCi10xVRYDlYQy0Qoz8p1f4y05e5e5cB3uaLNVfR5j82MpmCSAJbXjQKdkCUPoC2CqkbKxfcQimk7e+Pm63mwv7eg6OGXhIw+UOT2puxlIFmsCENRAbpsymfxlrK0QfnR3F/VtIFvbTaz9877yl/sxeFuNfUCQmNAXz0q1syP8iAtUyhYn5BH0BhQk1RRG0XtgNteJ27ymRXel7Wn0XOB/ghaLKkHnCwH70eeI52oGorOitQum2+pejLuXNawHITLe/zShYzP8EtvrqDOrNm8BJNnhfKSfunYLYT7Z91RWcFyLJfHhHLgo1a15qfZprGxDdiCZtCPDk+qvu40T+AO+h+YKBdEVBBDYr1ry/3jPp2pr0hrlyH9Yeo7PWkqLVAyENQwAJix2vNq/Y=

hoQkQzfshVNj5zpWvrx4yKj5GgS+EbmVNqCAnIecePQZZ4eCZFIVzWEgDzz3MmFFW5ihDyK9RKh1BdpU8cupvhuo7IyxOZODKbDX93zI51PDS5Zai3ARVpYwhl74s5+tdWoX7/FI/FeRkGxdgWQN3wg7YBCswxoLi9ptmQZS+8N9moLnxmERahQ/mLovjxHDgJd1nrHuKzbiisibbo5o/fydDNYBTs+Dm3HZO795Wwd2QR1f19kVQ98PWqkrbhPz4yeaza6fXRQoJqd5DDiRGCoKYN3MWt6BChJ0odd5zB7Xqwqxxl50rjsh6pbnWrqN

Haskell 中没有的概念

内置类型

RUpq21uHotUMI+uWqPIvoum1+Oso7kG36mcMVAevYbFPEYRMILpn7ly3i4cbGTWa

类型解释
Number双精度 IEEE 754 浮点数。
String一个不可变的 UTF-16 字符串。
BigInt任意精度格式的整数。
Booleantruefalse
Symbol通常用作键的唯一值。
Null相当于单元类型。
Undefined也相当于单元类型。
Object类似于记录。

hgY0w2VJrrCUGfwuGDowQyzLEMhpj3DHEoIaMD5JTSkKH5C7wtyJi/Z1Maivrz0v+nZfT0foI9IzEDPUOZIsbOsoyvlkgCIWB8kveweBJwVO8unJ8xWRIq1/5TXLiQkr

E6zdv+/XmCJqZ6qXlpqFuytaH+BD/FYRZSol7dIJir8hiAP1SoXHlFt8NVwMiQQSrSZKc9FpAQbWStkcu5ScIA==

    C3hkyEMhniW5s4KCdVwc/x2FGeAmFo6yr0vt155Pc/hHIEn5meyo60m1eSe5iyQe2iuZ2UFvUNMYglOhhMrhcEN5hd5nicC4SBEMs4IgbyjwSnbC7s6Pvi8LrpbvUd/8NYK7q3RyGTiRRdEwnHHe/rfhkw745gG5/j9slm9Td23FuS+GWIpi278byorHUBAFPxXTcbG5/5HEokzMvj0UAFLIOSVkluqYm6LW2hWIaBQ1BVJf8rRpfVEFPKDACYF6qsI6KPUV+XhSXLU9JgbhY3IXmWnulQjHgmM9pFTnxIO1WiwPJW5LBG261MSiWCpd

其他重要的 TypeScript 类型

类型解释
unknown顶层类型。
never底层类型。
对象字面量例如 { property: Type }
void用作返回类型的 undefined 的子类型。
T[]可变数组,也写成 Array<T>
[T, T]元组,它们是固定长度但可变的
(t: T) => U函数

3ht8cMfVYrbtwI4mQ2BsSA==

  1. u9HQ5CVsjQ9H056rwAAIN97GxdVkcNUa95a1RiV7sep73YiO3maV73WMsxL9JYAXdfmj/yAI0zBkeydM3+KMoQ==

    let fst: (a: any, b: any) => any = (a, b) => a;
    
    // or more precisely:
    
    let fst: <T, U>(a: T, b: U) => T = (a, b) => a;
    
  2. rPAndNbH9I/yR6Uxdx8H4XZ/mQo3gCuiV1K2UIGVl14CjwWKhCca2e5YdlTuRHFsBEVWPMisXIjwRV+6FW9dNIcwcIu3gJl/sFOuC8V4a5Y=

    let o: { n: number; xs: object[] } = { n: 1, xs: [] };
    
  3. OyKDBh1qTppIMYRXBQPMQbYZhSqMeXIt5509uzaoOtcAzkB1Kvc9P6RLUSi0EkOUAxCb+Uhh4q00icD5U+XfFS0IRCbRMzEO1lAxOa3tqnsqB6K5xmySk3GMXTD6W4H4Q+BTQGAYCcz/FidF594jGLkGGxv/bcjpt9gE6llSZyY=

盒装类型

gMkdS1g46lZnETnsCrf9BpFc6J+k4Vfsomx5ZyFPKLw/BlanfBxIpl2xc+o9il9y7i2qC5hXU2EtGttYxmj6SOc8uDSpp+E2GRoW0oA56bts6fEptNfJ0ftRG7JXT2qLSuMdwBbdalDIjgR5a5+m34iiy0bGCWlfU6EYmK+y0APS8eHHuRg70K9GYFgJbv1Xs7legsJapbT2hIO3xGE3Dtgyel9TApjp24evhhd4EaWjWBS5aLR2dWXC+1wqO7qST0rIm2fZMrYi4oWWSdB7WKI8tzzf+J20KmGW1b49f1yXk5O0FiZkmhp2+aZQvfF+nqXoccc8jZZLLQGytjSh1l3Cq1/GI1+xcxybMbhHBTH7jk7hKu5GYJVC4pAsZ5WOem9+ke82MqrF/lqhfmTBVg==

(1).toExponential();
// equivalent to
Number.prototype.toExponential.call(1);

UT+IUq8KuLmXdZcPhV/nMCfxiQ+wv0Wg2NS4Jz2N+dAj+5UiYwSSHH9IGEc4YbhCoR7fMhZmOuMa8rOoZJeHOBRUNjTJtnzgsTvWrEl1/d3Qrg6si2NufbajKtHNEoNq

渐进类型

T4L47DqTj9WA7p52EE+ahUZ/I3FR+q5LyxV2M632ziupAvL6ln4W0zapF86oeHtHSknBlus8WwdkvsrL9Rn9X5YvhaQSzue29w2WbuSbvw+kAXAnFEU1TdWQGzuyrfL33gt7Ty4udvkNM1YNJwHohUvQqE95lfqLsp53b61CyFmUmWxWDGPo8YfixoGBkt1n2l0DX0qbSwhb7YZZFeiiQx9ML+pu1c5Tu7gibDmHkJiMQfZGJcZw8DD4N5iiMeYgwY5ekviPbNOIcooEVbbHGOBRAHo2juJzSpNpYWyyTL8snbQ6nO70qfM1Qhf181uZXPp90PC5oSENg3nDPm+i23O3vG207ouZ9Oz/oyZ2fCL/MYgvuz3XVW5wOOgQSud1Pl8CkY8+LVMmGbNsffnPKj0Dz8kEXVVkt3qwT2uU9mc=

// with "noImplicitAny": false in tsconfig.json, anys: any[]
const anys = [];
anys.push(1);
anys.push("oh no");
anys.push({ anything: "goes" });

qVxD1oExqYvFTHEqcFWJeJoj0u+m91wp4sTZQ1FtKaLiCQv1bJH50KbjYw2TzxV3aGBekGAsg6AY0lc+hTjTj71ZZ696SPwcXBk0ZgtVJfQ=

anys.map(anys[1]); // oh no, "oh no" is not a function

UsCn1rvv49NHFOyIOXXFzv1RDFHKJqE5VV62Qx9d63pHtFG5RE+iv8WX0J//L1b3vMY5dHkO/fm0L4ifmrmp5JBU/S/1B7NU7jQSxr6MTh7ljZ11DpiJfYBw6QDYAthCeXrofXNh5EYPzyZztyWhXjw1510K5gAQF76ZzCpD4Cob61AfB46BMvlbWCxWY4uK3MwFCZGvECRDSKj8ZMbIhg==

let sepsis = anys[0] + anys[1]; // this could mean anything

Xv2gdnBmSPqqgmgQJomaCUPoV24WGCYGzayzZ+4P5XC/xEUa80ij10ak+/eN2fuevsoRdqagWW/0fIYcT40Hu4a0ZzZS09wpkLH4E1YksJBpuU9wfuFlyFV5Q0YRShIm9zJz8gG62iKj+BBAXyF+u8ovg7TiIxxVY1ANr8BrYaS9YFyCCgqJlBHnd5onfbqeabWzXRmlfegbz5eX4ms+0cXrqETNKQmhSeIew6JgO4A=

结构类型

f4/no4tLKY9/7wTp5PiItEla5U24gVOxYgcZ3GXViiPtxqF0LHIXPHPkfgswspaXWRiHbG24uvL09PDMFJ/yGVNHmyU4hcD0+PbSAJIe0ZPH/2bo6hA09k/P+cZXozvooJgXCd0nmBEhuocpBcUuaZ57OODbVsKwJeyWquuZ18/DpCLyDp7Pzt0Yk6BkJS96M/9WgRIXTnh5+xB2xlimIA==

let o = { x: "hi", extra: 1 }; // ok
let o2: { x: string } = o; // ok

cNrlKLtbyJ/HmPTcJcSPU5P9RzypdryWrVk7PrYzvUCcQPSwFatnQqzZbB+pEmEHn0CPtDqRQmCcpucDDCZzoU6ssTxpQfx3MTIXeNyui65XkLBKsgk8s/cS8MFeCeM2zb6PU7nNGJOyoDl1UhAHPm51gS4wQqC3lhzunXQkETniQs5nbE7pcIhKByxacbsi/pOdL/adCXYJR1hGnyl0UV8cYZCvdFOURJNMnABQZUYTVmNExzQ9unTJUpJzZVrLiB8HfLm/JOl0Uq7isjRvEriypQMrHX14fYyjrS7zuJnwMs0lsTz9/FwOCstXGMJCNiJ7X5v41Q37XQC5MNOHnTbb6ZGYdNSWpv+x2mUV2D0pFYLVqWp0xMqqTFKNRsNJVYru4wok0+nMDdaTiTAMYZmW4g28n45cKq3hpdFYE/0vPnx8bi0PBSJZzWU7b7JBmFnOrb5f0l6xYfvwSTV3BmL1jT9tyLy4Qc/AAjetUrQ=

2d5PDK0mjVDx9RJaLIgCNSnIVpOjd8PfW+ZxFuFMiT7EX3evIYT62OIYwl+8fyS9rH19Qdp+x312ph4zFk7PQr20P0xKH3AWBEPPOcJIcgYi2CkAs4DrwA7BwidxNGm0q9rMfb2A7a1wCJ3CYLZdVW9Yhpp//MOGUt9k+jE8G/bIM3RoO0Icqp4tUPNUf+1Bvag6q8e5iH0dPXb7uVIjELlS5pv5LTzxFfz1+iZecXLuie56k/FgV3B6Tr3htURpW3Ags9tbt8epT0iMsmiScNRvFcynMSbTc5X7XQskWhFUw/u15D6f24ooIFvsKaRZANXsxM7o/DuNIlbtZwqpspxsdk0U4YjKoaLpTBj1+r6aYvVhCE+NW1RtbwmytH5ABa9yrISvg0lKOHh/C70oXtNvlQd14F8oj5tkYSq9LUE=

type One = { p: string };
interface Two {
  p: string;
}
class Three {
  p = "Hello";
}

let x: One = { p: "hi" };
let two: Two = x;
two = new Three();

联合

EmeuTrhW2evpbxexnG3scIxBBD/Hi4FUp13CxLeI64IsHMadZKUkLra9yKUvaD5+G3baJ2S0y63cOazhsiXHW7kWU/vEUGK4ukHg58N78b/sxTcZ22cCzYoIRtZSatYgUKGeDAqolDUFzIoS06FO0H9HhHdlHUk8f3mJL5C5o7aublrT2p2fJqgz+ie1uN66HPas5ZlL5iq2Ry/G+Jo9b7WoL6X1OALtG3+mGScAVGSh+YnAvZUOLmxjSK5CZHfT26myM0Dz6iSHXWSrLhF6eMCER1uKEmXH1NTBxkBaaPm/bgRUwIcGjlV8hRBKp7co

function start(
  arg: string | string[] | (() => string) | { s: string }
): string {
  // this is super common in JavaScript
  if (typeof arg === "string") {
    return commonCase(arg);
  } else if (Array.isArray(arg)) {
    return arg.map(commonCase).join(",");
  } else if (typeof arg === "function") {
    return commonCase(arg());
  } else {
    return commonCase(arg.s);
  }

  function commonCase(s: string): string {
    // finally, just convert a string to another string
    return s;
  }
}

5U/dhboAW+9RHWo3PZ2fAz1GxwdIzKIi7bzcRZcC9XsYbchoB9bjIZkI/GcMBDaLGWDkSKL/x42iFB3T4lfJs3CTDeejNyUieC6jTW3adp6Fo8tkAhAjoBk1oazzSnruflLXLwUeNohvlXTRpwLVOwz9/3FKGK+7swa8JitCF7pAmMeST8+PfT89BCa4vXk/uXei8q3zHiajV8KI72iQp/q9rh12vDXlR+MRFYWbs0cn8diS2YCjPpyZDRKoTXl1ouJek5FVgrGLkNsjV4QykK4QaeiO5xsBNWa75SVq3dBBAsNxBfclqKraXuttQdBeKoyC6lBiL6Z0umcImHfv865WMqVrSvmXVjbyoUVfH2A=

Ck1de3twD3qiLau3e3WM+TfpomRCDqox8AUigZl2qDDWOjGXkB0noEdbOj4P/EfH

类型谓词
字符串typeof s === "string"
数字typeof n === "number"
大整数typeof m === "bigint"
布尔值typeof b === "boolean"
符号typeof g === "symbol"
未定义typeof undefined === "undefined"
函数typeof f === "function"
数组Array.isArray(a)
对象typeof o === "object"

jRBRLTiKdAXh9e2K26aMbOmVodSPqswwZNtrZMGS9y/V/BTVMsi62OUboGqECB2Ej8MHBNNbORMeBSiqa/BdB3zMFtQsBWqabokUMqO1pK4=

交集

Zcw+/l23iDwk+opx+Zbds1JUQg+GyVHc2QSziavcl3sHovyPog1JybdvJZJGisPP

type Combined = { a: number } & { b: string };
type Conflicting = { a: number } & { a: string };

Uz5BygL5yJ4+VBwMBot8WxfeFr7KhBPtNZ/fYdU3vvijsjN263RcG7AVdUagA203UQ+QMQh08Vxx9+2+4co9TGoiWjIkVmpNbUad4YsLVSCZ7MLA9VIexaTG1XroxGrc4S1C63DxfamALdN3ybzXDRkwzwxrF81Ha4UfnBLDLulNgGfaw4ArBusIv1HeYC1w2/S6f2EkSff+x1e65rZoK2yADPFI0o8SVAmhNzKOQV/o/GVNnSXCalW1+0cBXZSYmrX3JiTI2TgGNQrCollcDJLbjN/tEREfIOz1XkD5Pk5CCzVN14kseQRdikVr6Ovi

单元类型

PEHj8XtSYgYDX77bapYNLIx8t8kbycMCLkpfeS5vAyx0GeDMrhNua8HwOEw09jG9+KVLTjp7loi8vhzZYnxLfTAA32Dkxii4EbWRwgOqDyhs4bonm736ez0Ubzbf3eUIHpX0amKFqtGDVN2zI2Y4azpiCKF0nqSnznGKuW2htL1lbv1uff+GBHOYc6tB+Bfn8Ow0EjN33SnFfoTxQXGlWzPOuxe4no+Zx2mNqzDUb6wqyQ/pa64fgjzzIOgPDq4xmKRQ0Xj3nzCzs+30DFWCkLzedcXmLp9AMgxFZJDIYOO/+AWCJfLmHMhMaHAnx5b/njL6HueQHycGU8Vcx0mxazBVw2sGO3GDqVjPsfeMgWa4ACPe7bwKzdB4EQa+NgSWjB1SPyXoE9k96d23z0mZSwlDnI8oDUcECB4uxxGvHM8=

declare function pad(s: string, n: number, direction: "left" | "right"): string;
pad("hi", 10, "left");

T20SPQ61YgEH0XlAyrGBK50dV92RLhrv1yIXboxpyochQRaHwYYCiOfX/BAbHRo8IkE3BjqW0o+58hySq2H96279M0sMD+OjxS0H8Zw0TQf9TysQox2d00G4sCBHEEe9QnxVwg/jG7PU4BYA51kLQIRnHr+upr5C+sJD7IXeF/WBPv8kbcgwk+uJQfAuhjV4jPXhhdzyDIu0pUp7FEOHVUd9CWe+5Mp3S4ifXykFHLb+zV6xz+euxzMO3ae2CZwksJKkaIzKg9WjSsOPlWvs/fteGpayvRqWJX4ikHvPZYvhHbkDwiZhpNPKd22jSjnd

declare function pad(s: string, n: number, direction: "left" | "right"): string;
let s = "right";
pad("hi", 10, s); // error: 'string' is not assignable to '"left" | "right"'

zVOHbLiBO8uzHTcPOFtm0V2ZVSlNFtfjo74W1J5B1WnRlCz62r8a+EdkXWz7yUum

    Ai5b19bzeNxcyTAtzJ3KYywooiNzbpG6iW5nyMdc5zYKStSWNXZvaJVBcI43XEfGlWAv4zanXsk908mEM862M0TYzcHgwuOw7NufEcpCyX2TBXqLIfaqQqGO8uA6FnogD4wSRNyqybNVOxIBSgPlIRG0yYcX8IobjjSBmVLnVWLN4w1kxq14BJVU/ke+QBX8+5zwoCJTAkBPE20czK/Ld/fLhddm2mBICzJsCFhkiyL3pmYmdRSBmHDDXKG8Ka5UAtWaLAxTCWqMB6oqlj/BneyN3Ff3akaihH+yO8TaWxmtn68vpePqZoOnx8+gJ/Sk

uLo0cuMXmhVAtQPsUFtciWPqxAuuBRWrFY08mJD5+azhz3fCh8qJd1lQsOE/ZBZxNhem1qjhlfqj9evnS+Dfic8TuImUnPr34nRiiqqVOIwBcRCvTCpGirDeJvS3i682g95+/ZIcSHgwA5gAbGl0/fl+ein8d6xqalf0ebsjd4H9MiSSJWnp6lAb6qWYuE9XK+2kNMJVUNfRk7fK0/Q928X+CfLocapOcG8SdcLt50Y=

declare function pad(s: string, n: number, direction: "left" | "right"): string;
let s: "left" | "right" = "right";
pad("hi", 10, s);

类似于 Haskell 的概念

上下文类型

ghhTViHUdIBebF6pHB3cp2lIX+uDYal4JFfCE+nUW6r3L954MhDqIcRFNrx7i86NTQM6wzFRt06eY2pXADaOfEYldlS0XVfMd+YLr40n0ps=

let s = "I'm a string!";

uwWPtkZBP8far90Rwge5ZIr0uFmjmGFGD0KdeQCWTpf6K6xguYwYJO93uCNRj4rIFlY+qZFwBtQ2UOg7gUsYOagMVkBxbLsKudlyWM4Ttttc38sPoh07h5BUTbqUuYDaOnQstrOdwhIpPaZgrwmzw7ffL/+7RXotW+tqQ1Om/gQ=

declare function map<T, U>(f: (t: T) => U, ts: T[]): U[];
let sns = map((n) => n.toString(), [1, 2, 3]);

o5WuMJpK7zrsZkmHJnUmXMWKnK/1g/3NXaoYAQ9jdervJFQ83J4vkUTLe3EwetblqpPqTdtahgQ9T1SZCuxr31P9lGkA8Ma2mn/UUF+p5FMbIezrPQ1r2HWwHAl4xDHEu3emOB8GvqneWbpwl4e+fi2y9nMgP/UdF0fVnr4V9kZhD2kvUlFRA8x99WNOhU6dlpdwfEATkwCJjgW0M4WPGBkx9FMFV3bO7nWpblPrq+nZ7nL01wAPZw97lA2cXeH3bDZ5kGi+W64OUYVLkI/lOu2OzsrMi17gsh09pMe3i58IWP48KvTki/lvNTiubm7fNDMhURP4CyBlrHQuYshPaQtuM+lPUruI/gFI+hS0SRJxSiP71rPyztTZKkNSQwZkSGPWR0KkthdCWSR0mu/Sspu8Z2TsYEVA14De+fd3605RV1AiEdGABsU91gSiH3UpUgE7AY6Sa2xYWhwNOrFJk6vhUNMPhbPjJYayATy381M=

jaUAiiw/e/n2e4kmLpT4HPOSlWj6yX4dLvUe8mHgwJZfbmJJ+H2H77H0uY5YTjFWshcYUPBzB+4Ro+WvguqBroRvReTPaQQe/8geAJkd7+TqccdikxsSkF5K9npHc6sxs4DvZ+/Rae/I0RlL2lZee3cVxIeXC+TAbngFBMy1MMNpEvuHJJmmEJR6gVky0x1i82YrdAEAODfjIRBQos8WUA==

declare function map<T, U>(ts: T[], f: (t: T) => U): U[];

UWdxrMZVgzoqLZgfvMrW9KxHs+i/Ln9kov7THhxJCMJokB4amSHta4/ML7ttgg3X/aojvzmrUJEXsVnIR1jbpkHoPYaZfAaY4kxMGf81zHB7N2NNaQ9odyj+2AnlBKDUZnYk64E6E+PVSDz17OYaD7X5GQbHOwjvxzVVbpffKQe0DK/JthkPdAQwTXMegd+wQ/p4V8cXBqe0CFPKaLxhzTBoPh3otgIzQDQL8odeyuuBfvQUD9eXYPAzwNUyBAf3jaOOpaSJtItlPY9dXGYo9qf/rSW7HRU1AaM8K1PvNsA=

declare function run<T>(thunk: (t: T) => void): T;
let i: { inference: string } = run((o) => {
  o.inference = "INSERT STATE HERE";
});

xtPxX2/y12DX/ez9SBjsUDQktwsMOKWo4Ttuu/z9LxJFfqNT82vw4YbSv+4fL583s23fMap+4MPwhKGz+/l3VJ216W+C7i8yHFIVJHnIzWo=

  1. 声明初始值设定项根据声明的类型进行上下文类型化:{ inference: string }
  2. 调用的返回类型使用上下文类型进行推断,因此编译器推断 T={ inference: string }.
  3. 箭头函数使用上下文类型来键入它们的参数,因此编译器给出了 o: { inference: string }

bBc3cEypR8df17LJadZNdHn3y3C22MmRsm3MIrD2W97+UkyDNqOOgEzoimYFoI2pbF1YmXp5uYA761eAOzlyfPT8AJz05YWA7EREf343OCbcx1w/Tfx+dp844YKvuohnlL7BcvJcKAfq8JkkBQVGtJC7rOJJQAQf9xqyvq1KqI9NbirnQcR8fiRDSA/U6MqAdpLw2wXXsWacxBYIGIRS6xrTCiwefbRogOHpkjAiiggK5cv4J4w9LGsFrgwp3EruzcfbHbhh8eDWA4Kv0mV+NRJ+0TH/+qsJkOvDora6a/+lSipv1DPCtyLyM6ukxA2FgUmT854GponngxzRpr0lYbgVKiE5latEw/93laXB/TmMG0AklaK9xNdm9jgSvhoMis9AdjQZYn2ynJ2RxHjkAl2TT4Gh+6PDKRlaiRV/28QUMy2oACtftxdKfKDM8l11

类型别名

jJmuR2dliX/nxRjrGFEmDzbeHXQYMu2AO07sMuQdY+foHYX/BEjw1U6P9XY0bCrOyY64AA6ewY8UFxiVpo1hVQqAo8UMdxavUSq4x5O6DnBBL9OEkp4tpU6a4DyRXSsPgJN+LTPN61vUcxDEoML0q90bP/fxoQE/EJ0Fae5b76K/jdK9XX3zWqfH9be6jNJi+BtijSw/uEuaQXPuLuxWb0or/pQ25nrFdScTZBkUaGA=

type Size = [number, number];
let x: Size = [101.1, 999.9];

V5y6y1BW8nsq5rdANtMV4dpiDdd0eT+LHxs537FwagB5hvrLxmh7i/25pI/4rJlXKNGzM5FDrPDyGqCSpevT9QQfyOUJw8YPuO46PDEkXgE=

type FString = string & { __compileTimeOnly: any };

b08E1u5wmAsTZIt9OkKnNf4bHSqKOEZCPvhfwkpszGlWe40GTHO0zCbQHwx1Z2DuAr32zTOpqNQFDDEaC8rjqx84ACXrYWaRibgd7OxUdIzCYvIupNutXboXConFlFT5L3ieq+q6/FOUEiiD8Mbn6Z0nnGg6Phn/S0EQsfsda0i2tPPehGeSL4Na2nspq9V2XHeR9ISyiDlF8GKkPPzko6xqYrH4oijONZyFMG3DWjKTdZNEolDtXCLdO206HsG2G9QGpjRqBpa1dH9cCFXPFPrw/Fnrn3XiKWt3v2zrvzbibTssqHGuytESKEx4831gb4oNM6/vdigPYH5rDiRcLPiQiExb2bhHJYZmgtEAgMQ=

判别联合

rLgtpOL6gGT1N7EwXsur4cYUppE/qLpFCw/LiCZ3g7nFk2pPZ0TumOoeoPvnCqyIvShXFOo/f/uPhVEDJLOSVwA1BmFF/ApdO1BIdjNJDbB4NWGtu5hEK87x9HEHPSBvekHsmDMoBcvIq2khIUJ9sJKjU56livz9lNBMB8pEY8M=

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; x: number }
  | { kind: "triangle"; x: number; y: number };

tPJvrJsSu426UVgUhRwXWIwSiLOP/NPJ5QgJb6fp586tp29m19tXdIuYWpcCusZVkD69Nw98f/GwWfuq7ywzjqZ3Ckj59xQ751tRw0JXayJ6xxmZhIG9oO4J7pFQWdETXQ/YE7Lo+8LZUGsAjbXvRbi7vt5hcHAgabg6+Srj/oc/Mr5EYHLO8KKgbs1RzDFY7LXpJnIJ/mSVl7tkYG1O1vuitIyhQu9iCAz95CI3jwBnjwui3NTlG414SBJSsgwMb/18BhASV/DBkrwDlQshbx110H2Woc9yK6USz7hBynx/auAHgOSZ+tEcCMyPVm3GkBbrrM9L7g+DOnJnRJYd0l8ZPLmCm4sXcdfYZrj08FOZrLuTJHCI/RUPHbMDVlbqpcEq0BVw9We9mxsvHXBltGSncxCjVWfOaIYa4KJjoFVsdCysu+ZQ87OmbpfJtyaa

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; x: number }
  | { kind: "triangle"; x: number; y: number };

function area(s: Shape) {
  if (s.kind === "circle") {
    return Math.PI * s.radius * s.radius;
  } else if (s.kind === "square") {
    return s.x * s.x;
  } else {
    return (s.x * s.y) / 2;
  }
}

hZZ7EMBxCWTVMRkSdoq3xi+KIKHvsxPznscLPCw0EZKJ6fbM4/FQZH4Ixg8tsWyF1RnjM8uYv6xJf/8RwdeRm6d6QiAqT8eZJnm/OEEAE4E3kUcOJ1XrQXB0lVkbZdpgCwv6BFepehbaFrKbfxN5hfWWz95KpJP2fj0E1xyXaHlGRNwIaFFgtM3dK4qn+fGo568wpGb/y0raJzH2HTc7OPi8BzFOjuw0ihhIMJeTLToQccCLDaBR2qJmAbB5pkbatxk7oQlY3hcx+RSx00i7tySHREnUUvVr7Q7ir3aMPrpWuYy2yTSG5w82Ka3uTVY0

w/PoMX3AM6TWZbPUr26kdz1i3qhe0G+YKQVqt22p45IxG7bPKBsO+0ddL1YX3r1DZQos0BCeCiAIBiyEuJutu1R5mRRCeJO4oG1XDn0qb55qpddOYFTSKk21ujDiFeAi5q0XQxib6EZiYpIiwrEvGsfhDH5FWITFZmRJsE95I4hAPJhNgSgR2N71TUMo3pVh

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; x: number }
  | { kind: "triangle"; x: number; y: number };
function height(s: Shape) {
  if (s.kind === "circle") {
    return 2 * s.radius;
  } else {
    // s.kind: "square" | "triangle"
    return s.x;
  }
}

类型参数

nmELmRbrFPPh6Xdob2ewPokuqtEc194gQU2G3BerD/r/f4KnAHoyj5Odue4y5xv6+uGG+KmSpNDJ5efZIyNtxvQv/ubLx1z38MIRDBgminA=

function liftArray<T>(t: T): Array<T> {
  return [t];
}

6TKgHFQamS+23ULYwKEraRtVbE58i0JO4Y3uwUf7IrRb1eKXx8gLzLDruoG1wLNN90mFGncDJLSUJb1h55Men1eNPOQ23/M0cTjPGtXa9NaTGdCru/rgOXmFO0Gggo2QMEc1E+4haBywhZ5QS+kToFdiwjkjF+BkwV32XbnTA0c1I20aBHclzboTb98QOxSIOhSO/W0RWvgS/+UTERGv9A==

function firstish<T extends { length: number }>(t1: T, t2: T): T {
  return t1.length > t2.length ? t1 : t2;
}

zaSkOBa3WatSafH7YngWQ+7AADkwl2LUd9F1WY64RSU5cAJOatKKYgWmxQy3zPj5FV52iadXetLCEF8+5KW4OmmYZfceDR9ROBB1IK9ofJWHgFy2r3LbQ1KFJ/8Hasj6m0yoZKQsyYS9U34wqIWmyuoBCx6tb1wQNuTJUxPio2c=

3c4jjVr5BnRBy+c2dj5u1Db9Xvc1fJoQAwyYe3bnHwz8gSH0OdMMWXyEEyxEeHWaTfRd9USZS/gRIO53XR02Bjmq4EPoZxjLtHnt8As/esTuuMJvIl39m7vO3dXy3xV1/kxuwfz9TXFYncaU9O4tyQp7eWie4Uj1iujWDuKwJNLv5hw1W/xlvQJNYOsWESe5sy2hXHR3cQLALZnFEHcL3Fi2TKRcOR7cJa23N2cjyj73Tyk427+nGK0N9aunna1BOIGbJwaM6SrRMfam+7QjILREBcanlJIVus0lvj+3zeJEjxl1Sd2LNOE2s6/LKKo/

function length<T extends ArrayLike<unknown>>(t: T): number {}

function length(t: ArrayLike<unknown>): number {}

QjILhJwTAZe42ArvZqwDmr+Q6alf8spt9pFWuEY9xPNXHihd44TFFGGTro9t5cY0CZVmT5STbUmfEC79mgY5lOhmI0hD8d/FGR4VZTjXvBhicG8HBeR79TiNJXa+LODBuwo7LXRE5o9ysFU0cYVCzsNlHS248uYR4ylOdmpNPat7d23lxgeXbRdMz3hIvjZ5Yqfe1mDtDUpk/ZRvZBi2cg==

更高等的类型

8RMrVN1yOh2KQwBdASdiBfAQF6MYbT3KMARzCyEYm60/As2Bm6xO7ZSsO5SM2SwiiPN9fa62hI4LXz48LQ6tWryH6FEhDCLy5nirZRxOh6E=

function length<T extends ArrayLike<unknown>, U>(m: T<U>) {}

无点编程

fZ5Hp/pTGRw0jdD+ioG2y2dIbIPxknaN5DTURqP20QlPDs/cQm25csvEZh9FFaxJCUoztLPx9M53UQY816SCGbB/fZLNp244appsFRvr/kHZINBFppufnNfj8mawu/E2Lq3hQGJLWWAScZDTPc9HEp9PaPsFVf3ILgqOJ988G/2K9dnRnwUsfe8gjZEuItdue0kNaFQlVx++hyu16wnCCFrc0L530KxvJWm88zHH7MJAv5Ltn80Ft5DOea3yuoyiQU8IbaSpciYNqE4HDVSFQbk36Z0VR2m4SidKT8EDDZRl0Rn93qJX079TToMIk9nk3avIY2D6WwhTxeHad/Aq2aaJe3xyyUnPiqy/tfARK/FkQYY3+n1Eg+Fob6O1BVwt+CE/vkEs3UK3N6gVwSObCg==

模块系统

O/ok4Ovs/rYFgZ/+4RvdqE2AJiLTuI2K21Ur7tgLR4bbzCVe0paX77nmyQPRRMAP7VUEdl/JEQ49xE89vborHl0r7dgHmx9IDhQz4NMigulZpnCPcwO9FJrTRDIcF6XZg1Qaf8bE3yg8u9+U9wk0aPxED+xiKpGzBzzuSw2LpmWmulLE44YILZz98Dg7BFMGVM2cXHcVdNLKwB0uspPsEg==

import { value, Type } from "npm-package";
import { other, Types } from "./local-package";
import * as prefix from "../lib/third-package";

+hEc8UuamqXQ/5wQbpjcf5rqWgewY5Mlhu2g8E6J6EPgkA3rnrPEEJ4fM0Rl3mSu+49c/9Vua9o4dUXXrPbYHXIZJqqOcGJ8y8czNWiwjXMgwYPoFDTIoqwe87ooCB9n

import f = require("single-function-package");

RvJSbgccx+r3Mge6E/Cfq4P92fZVNGF1cFW4A8vPkMSRmWw5RGP7wlUuGfwH3ul9

export { f };

function f() {
  return g();
}
function g() {} // g is not exported

hx9VESSBXlI288Ss98wHiP1nBE4HN10X8jWKRc56R0CdGEqsH0JP/w4zCfNhKtKq

export function f { return g() }
function g() { }

0ZngH58W6LtklYHX/TewCeNllu/5cPc3deSnyXdcYFCp/Omg5gL7yV7jIOmfKu/ufdzr2AKd7MQJpQ2V9QhgRDL4fr/kUmelDha+p7CUCw3ZDou3ol30j4CJ68izEP3cP0bi+STGivT6VjDJXA2K5g==

readonly 和 const

KWMCewGuomcMoIJx7bmAlcgbzLa0w4McjgsKhuqbBSzpwd9AfuksG+4Fy5cXAAcJ4DqdMvdSLuVc+B9aaMzhcBL35dbWUo6R7wSztZ7mKUHKSEYzHIIp4tR9TVUFB1re30ZcCdFjRddBsgJm8Kw8P0eikjhg0iCDBjCsgvFXF7fNeiE70mnY/Cmlpu6RlDZkuAoQSxjbXvZ611TkXTrSICjzV+wWGeWEqs9XwljHryM=

const a = [1, 2, 3];
a.push(102); // ):
a[0] = 101; // D:

X3oMvhJxKdPtXmc5t5IC+/7iKVObqw0OiFmkPbLm+65mIoP6Oa7mmWHwNdxJwZAKDco4O2gXEN+8O+9NwPPEISrzMoSLjd0+JLD27PJvGyw=

interface Rx {
  readonly x: number;
}
let rx: Rx = { x: 1 };
rx.x = 12; // error

mmFe5iSaGGLAqJC0qNGW1UEEIjWqz5q0Dt8bXIFOXnsyIYlIOFQmFXmUP84tUDTPL4Nc3potzg0oy07JNmycnT4/YHUbs4Kh7E+ImgWypbFSuwvFWfcbjY/968HvwhVxRn8i8bqR52lFiBKJDgpi1Q==

interface X {
  x: number;
}
let rx: Readonly<X> = { x: 1 };
rx.x = 12; // error

3mUeL82TTAp53zmkOoK6uYmh1JecPOZ1N37n8p8mvat4biuvrQ41Cf1lORQL8EJjsKbpJtA2ZTbTv00Qd4pgzHlhkjnz21n10QREllm3P4XUJYtenCPel9nCI+AdqLoUGdKtLwlo2tjduZiFXAWTSFaevXLyiN5ufpUS7QMd6Bi6HG5gcBU8SQKhORyq54UNuRJ0cI48B7JUkuT2AgWnBxbYZqyn03OdJdxOCyqZtOQ=

let a: ReadonlyArray<number> = [1, 2, 3];
let b: readonly number[] = [1, 2, 3];
a.push(102); // error
b[0] = 101; // error

Kg6FTvsXfPleCxA0tWapa+tA9HDfOQMcSALa9dQwC2H4bbABPNYlBNEopFo/yoUIsu5Y4Dg+s2C6mhcb8d7lMIE7OShpE/4kAo0K8xCiEGM=

let a = [1, 2, 3] as const;
a.push(102); // error
a[0] = 101; // error

1cwMHXaTAjldL5G40HQRIGxDZzk6D0ZNef/Y5hV0k/1WKp4cSNNR1PSfZC/aZ4kE0An5k8PSmiunKzf0ww4EfRxXO/lSaIsSEY6IaLzVhXH1U/pZhWKYtjAe3fuMgjI3JlGeOztPbHqIgtimQbuMxw==

下一步

MK8MOijQWMTAspQaHTSlMSYK18P1EIpZevf7zYdo2YnDd8QvvXzvdwAz09ibCfQIZSg8KGh3QMl7eIrEtz0qF0BVyOffb2YHmtMQcMdIMUjVPFUXG62njg8N5dU5c4gqoJkmCmFM/tjef+5DeJLuAA==

    UN/dV1m6H6f/MTOfi5jIyjuF4BfusgGTvVgOAEZMshodkAITP4lhN9yeNggNxfojymBR6Yva7aODQyvoB7xE/sE/gzCvjow0TKUE8n/QvxnohwqH27tthXM1Q9Its/52Wgv2TXtqacd3NkFyQTqecc7IlB66iyR9kjh+Im/dzUBfJBUUidhKC2LPJj6JZTb9uPnvzHkWf52Q3UJfQ8d6Hij+jHh+FWq0R/Cu5i21NMf+bhsQvXBeRu7xhu/DSyJr