面向函数式程序员的 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 | 任意精度格式的整数。 |
Boolean | true 和 false 。 |
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==
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;
rPAndNbH9I/yR6Uxdx8H4XZ/mQo3gCuiV1K2UIGVl14CjwWKhCca2e5YdlTuRHFsBEVWPMisXIjwRV+6FW9dNIcwcIu3gJl/sFOuC8V4a5Y=
let o: { n: number; xs: object[] } = { n: 1, xs: [] };
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=
- 声明初始值设定项根据声明的类型进行上下文类型化:
{ inference: string }
。 - 调用的返回类型使用上下文类型进行推断,因此编译器推断
T={ inference: string }
. - 箭头函数使用上下文类型来键入它们的参数,因此编译器给出了
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