该做什么和不该做什么
泛型类型
Number、String、Boolean、Symbol 和 Object
❌ 永远不要使用类型 Number
、String
、Boolean
、Symbol
或 Object
这些类型指的是非原始装箱对象,它们几乎从未在 JavaScript 代码中得到适当使用。
/* WRONG */
function reverse(s: String): String;
✅ 请使用 number
、string
、boolean
和 symbol
类型。
/* OK */
function reverse(s: string): string;
使用非原始的 object
类型 (在 TypeScript 2.2 中添加) 而不是 Object
。
泛型
❌ 永远不要有一个不使用其类型参数的泛型类型。在 TypeScript 常见问题页面 中查看更多详细信息。
any
❌ 不要使用 any
作为类型,除非你正在将 JavaScript 项目迁移到 TypeScript。编译器有效地将 any
视为 "please turn off type checking for this thing"。它类似于在变量的每个用法周围放置 @ts-ignore
注释。当您第一次将 JavaScript 项目迁移到 TypeScript 时,这可能非常有用,因为您可以将尚未迁移的内容的类型设置为 any
,但在完整的 TypeScript 项目中,您将禁用对程序的任何部分的类型检查 用它。
nY8T6GPjMwvDyOiS4tmoNBAI3KJCXqyLX/V0eOKPgxrLHQqNYHcM4yPCLN2F2FzDkcw/oarwJ+kaxpSGYNtflUQH+RLCsKQ9FW7BH92zau77ZmRDvcc8v6LknjRuMyrbUOf262T6LkFDRtH3DW63xxOvEXbRusQC7oplpXmXbbDGitMNhpRt4X9wzXzkg0g4hDZsOuWpRzDtHQZng4GCADCLGIJxA2aefBzBEpWKIhLP880N5vNeFcfD6+3vfW7Pts6Jh90UCUFWt8ekOC6U5WvwQCeUg34I/cMq2EdTg/0=
回调类型
回调的返回类型
v/UWR0l+smJc+Bq+CwAihao8jolwnl7vYkTxWHjO3f86q8XQujD2E6xQ9kDOKk25/RJPZwUeVNofNa601OzVhScxMApEb1tB6Nc3ThX+e3s=
/* WRONG */
function fn(x: () => any) {
x();
}
mCcte0t5IHBNf4KhvZ5Utwcy6MouU3CMP08BbQMzuG4uKEgCzH7d20YxBugqA1Bt97g8bvdARwJP3S09rhF4rIvct8rATjre6pxsqvK023g=
/* OK */
function fn(x: () => void) {
x();
}
Nm9dZK+u9XpVzDTjpNCnmt2fqV+P5x5JuFQ1qqJLF0UTC4Oeh7UfgHzIFhVOUOcgA6t7LXQZ0f5IJXrBDH7KUwe0c2ZsQDdYrd1e/QG3Mth4w9rmcDJqoyuO5mN/TQ1EUZRcuoJGyfLHR0vzcmXoL+kcOHMpof5ny2cyYSXVCSi2P/zOx+SsP9XF279/MkBUcuNVvF8wE4bfOorK13Nbub+hkZi7ZZb7ujdaUwhUtPw=
function fn(x: () => void) {
var k = x(); // oops! meant to do something else
k.doSomething(); // error, but would be OK if the return type had been 'any'
}
回调中的可选参数
D2FL1l+cd9Hx557We7xx0/c+xg9RrjnZRL4Ix0HWIdLe5z8qAPvE3LOGQLm8BhvJv84qwwM1fOzxmdbIXf+inYmuYFAhL7Fii7cxeVNTTA8=
/* WRONG */
interface Fetcher {
getObject(done: (data: unknown, elapsedTime?: number) => void): void;
}
HaJBhT/q8sdHoCNm0F2JjxHJKgkz8bFXLKHvCWzpm2Ypg2/UjreVHOLzNDrchm1LcGQf4Q574yaCcJTXsILxxEpmrrOg0wP1metL6HAroAsfXpV8yFVzKtwSupqFWhuaysjdi71sQyfQWRYr41/FHlKVwGrARxhhf8dEMyPakvYFD9WTZq8iT3LkUW5Tv4KfU+37xq8piQHHT6EVmJL+LHU/DgM0VhumDPU3/9ND6I/LQWYuDf+5iR5qlmCLhiLwC9+h2YHSAdIZlWDAVg/d9rSdkIxGfDtjbNAZktZzrhNgn30F8Y/bF0OPMTGalc5ucad6aQSfKlsxWRigktZ2o5OTJrzBJ5JpA1S7CzIepPo+Cp96nvoOP46C1yGdT4saW0Bp00VFKQ2nTT6AP1Yvbjlh+VHh7zZjkB8HWcDQOSI=
pKFq+gnV2u0ZoEX3xRnD1B61cebaOAiaBb0jZrzzQpn2baUiZNJbFrxAB9izWL9B
/* OK */
interface Fetcher {
getObject(done: (data: unknown, elapsedTime: number) => void): void;
}
重载和回调
vGb3zYcUK9/gmk6DFdjhSqlsckkGvGvngxd47BZHeCo/W7I9xuZpAYEj6Wod9OeAG6zIQZ/U9yyNoFC4Xo/0hw==
/* WRONG */
declare function beforeAll(action: () => void, timeout?: number): void;
declare function beforeAll(
action: (done: DoneFn) => void,
timeout?: number
): void;
arNmH+FKcP49LZ7YVZks63QeB+Ym2kKjUC8cV+d99wG5jzbZeSBc49gPDlA4eeUvP86eXSRk5GXBjqSTFLCCJg==
/* OK */
declare function beforeAll(
action: (done: DoneFn) => void,
timeout?: number
): void;
Nm9dZK+u9XpVzDTjpNCnmt2fqV+P5x5JuFQ1qqJLF0Vea2lRFPndl6FO3VygUdUdD86zrCPjmx3AeeuHzc00VJA+ENxOrh9NIjvEodgG/9IZgsplHczrUAZ9PG4wFM6be54RiW5hhFYbGUMUnxG2cjI/ynCoEErRzOhsx+PMJH2ihzBZGdH1t+Pip4oL01n/wGBn1Jua8DTeEnv3XVmKgCFeRGgsulOOOEbI18XbgAzoeqOKh8lZABz/Um8agZxhff1FEyyB3RnwrD8MrvX22jUWu6b6h4IWKYrmyfv2ZjM=
函数重载
排序
jFIDNuIbQocmkqBJDbgCEMo0StXX6l48NkQNgwfLRRs2GOyCkre6zVBrl0wCd9tAOzjgLxA7H+9Pdhquvtqiig==
/* WRONG */
declare function fn(x: unknown): unknown;
declare function fn(x: HTMLElement): number;
declare function fn(x: HTMLDivElement): string;
var myElem: HTMLDivElement;
var x = fn(myElem); // x: unknown, wat?
xPkEySuIsuDkra/QEYwisk1/6TFtABCcaf0l5QDIPBKb88pY5RsyuuWIWVdFE/aBXlTplDLXf+YAF227OXPuwT9HQN4fx1qnvbSGO3CyjXQQGrdNBwFieg53umn5C+ck
/* OK */
declare function fn(x: HTMLDivElement): string;
declare function fn(x: HTMLElement): number;
declare function fn(x: unknown): unknown;
var myElem: HTMLDivElement;
var x = fn(myElem); // x: string, :)
Nm9dZK+u9XpVzDTjpNCnmt2fqV+P5x5JuFQ1qqJLF0U2yRkQ1g7jwajmvAhVXkMUnArVaUm0zkVInzYDDnRwiD9LAOL8d9RmsoSatMznwAdPIyFdrMOioI4dYYySQJhzr2TIEGIWEjrt23D5lWhbwnQID4p5SqxfK1JqEbEXrdBh15mPZSNlPuak12FX08qyWPGSdI1LzlRS+hPoUVLfau6+Pdo6NW+9ej8DUkIwCOOxpFC8xCZsr2uRRJ/Er6EgQncB+o/Brpa+/vZyfLJskLEkZ4EIJc8+kcYjg6Ayelg=
使用可选参数
vGb3zYcUK9/gmk6DFdjhSmHyYdAV6DL/Px0VscHxngyM8+ub2LZqkEUZ/KmH1IpxmGMHJHCjp8Hrr3UTuFwriQ==
/* WRONG */
interface Example {
diff(one: string): number;
diff(one: string, two: string): number;
diff(one: string, two: string, three: boolean): number;
}
h/zHjvR4Hsp8oXyrYWIy73aJw0jYbBkIQZLqXNzGrxkN2XGJi1/qMJKDspsarPjD
/* OK */
interface Example {
diff(one: string, two?: string, three?: boolean): number;
}
itZvtHIg5E58/7QzOboYF0AyWRdD6/RhcnYunPNSOIv5OXr3YYpBCgIZ4ervJMKwq3oYMYrFEbwaYYYExp2rNAMp59NKFUlbcrrkDtRctUBROBI1h8176k9P9V0tRyt5Zn2ailqxRTMrSca6tlku0g==
Nm9dZK+u9XpVzDTjpNCnmt2fqV+P5x5JuFQ1qqJLF0XnL+QYiPInhslNnwM0RIiYSgvAbh3xKakdJtP4WDfxnA==
ec3l3E9Ah0H18bY8QNhE/rr9rMvevNN3ZZnJL7EoK6X0z8yFop3qTaYqiYRwupvWW9dmn9PvMSftP4k5dDGiR4tcz4/LcfFCU0ETCxzm1HLWRFiV5/RoVTDy2cqXKNZxDtgbh9BAnCxR9hfIz/Sl1jBm8998s8yyTbU7scKKXgHpbBGb8Z6HHaAQu1Qao0OnYxExaotX20NfPY9+JHUG6Sd4YtyxceBvDuVG2IBeE3LeJu1AZc3IqMIMeRFRKIqw6OmDsFY+RDEONOH/nMxk429bpevaCIrG/iQLhO0t//2MBBKCfY4+1lc2HSCstgRX
function fn(x: (a: string, b: number, c: number) => void) {}
var x: Example;
// When written with overloads, OK -- used first overload
// When written with optionals, correctly an error
fn(x.diff);
+VaP8l2L6/eb6XvpBIpcUEx5vsnoL8cHx7yT21zK6NDkzJlaa//x+ZEs05L0URQHLmQ+nrTqt0xfQWQ2S6JdCW+lrxff0xgUfyMu6QW3t0ZjUYUzQ9X/tJZUcqSbYgh0Pdqfun9uaJw4uMnc9fw5sM5uf5pZol7jO9krUFv4UK+0nnNWDvLdMpDFIiC9MYJ/IpPis/bvgX0/4KSeNiTBNb7adxjkcmV8BSQTn84b6KGVLw3KD/N7R0oXiZ53UqzVctfhbZZ3xyYfWNyqeqplFiRzGTNOIITqZ5c5FNZ0BwnLadt1bZZqEFtrSiF3gIoEjsNosSX+o/b1vlm5foRU69ydkxsfa6/T6tlVKiXEzNll8y6SSe4eO4WC5NT1JN9P2NSuPx4z3z234wuWERf01zmHzUnL2bGkssRfTqgeshU=
var x: Example;
// When written with overloads, incorrectly an error because of passing 'undefined' to 'string'
// When written with optionals, correctly OK
x.diff("something", true ? undefined : "hour");
使用联合类型
U0f+F+JQz5C7G8ZTQZZjaS/D6FHTcWkYNePZewHGIeLus4A1CKuqxWR9HyrA/HaOvNxyLJ7dU4jnQNbSmaq74SLUZd7JKOZMIBJq+L6YHJ8=
/* WRONG */
interface Moment {
utcOffset(): number;
utcOffset(b: number): Moment;
utcOffset(b: string): Moment;
}
h/zHjvR4Hsp8oXyrYWIy75aZX1yX9Tx/zdR1yNnl8yhWrQ27NWj6xri67j45+edc
/* OK */
interface Moment {
utcOffset(): number;
utcOffset(b: number | string): Moment;
}
s5LoDfGjvBxoULHJFEwwykwtEbMEupsg9z3tvOkZSCJjTVcE4YscR4LTT9SdLOahxlMmWCev0ywxWfBy8dj6gR+nJNRarqoUwNyBzUjHOa2Ahko7tYRCIEvB4vwG1Xde84ZcECsepvphw8J8Qh9+iw==
Nm9dZK+u9XpVzDTjpNCnmt2fqV+P5x5JuFQ1qqJLF0U6bscx7XYUrArtqqPcwvPxYy5owukgxzlCPYoUgHkioxvx/pOMXaxnuqZeE94BsJwXPPKMPrKK0hglTjWckUk9qcQmZcgMPAQ1ikXSaC6Vww==
function fn(x: string): void;
function fn(x: number): void;
function fn(x: number | string) {
// When written with separate overloads, incorrectly an error
// When written with union types, correctly OK
return moment().utcOffset(x);
}