一:类型映射(Mapped Types)
const data = {
value: 123,
text: "text",
subData: {
value: false
}
};
type Data = typeof data;
// type Data = {
// value: number;
// text: string;
// subData: {
// value: boolean;
// }
const data = ["text 1", "text 2"] as const;
type Data = typeof data[number]; // "text 1" | "text 2"
const locales = [
{
locale: "se",
language: "Swedish"
},
{
locale: "en",
language: "English"
}
] as const;
type Locale = typeof locales[number]["locale"]; // "se" | "en"
const currencySymbols = {
GBP: "£",
USD: "$",
EUR: "€"
};
type CurrencySymbol = keyof typeof currencySymbols; // "GBP" | "USD" | "EUR"
二:Keyof与泛型(Generics)
interface HasPhoneNumber {
name: string;
phone: number;
}
interface HasEmail {
name: string;
email: string;
}
interface CommunicationMethods {
email: HasEmail;
phone: HasPhoneNumber;
fax: { fax: number };
}
function contact<K extends keyof CommunicationMethods>(
method: K,
contact: CommunicationMethods[K] // turning key into value - a mapped type
) {
//...
}
contact("email", { name: "foo", email: "mike@example.com" });
contact("phone", { name: "foo", phone: 3213332222 });
contact("fax", { fax: 1231 });
三:const断言
数字转为数字字面量类型
// Type ‘10‘
let x = 10 as const;
四:高阶函数 (Higher Order Function)
function logDuration<T extends (...args: any[]) => any>(func: T) {
const funcName = func.name;
// Return a new function that tracks how long the original took
return (...args: Parameters<T>): ReturnType<T> => {
console.time(funcName);
const results = func(...args);
console.timeEnd(funcName);
return results;
};
}
function addNumbers(a: number, b: number): number {
return a + b;
}
// Hover over is `addNumbersWithLogging: (a: number, b: number) => number`
const addNumbersWithLogging = logDuration(addNumbers);
addNumbersWithLogging(5, 3);
五:工厂
工厂模式的存在是为了解耦(废话,任何设计模式都为了解耦)调用者和被调用模块间的关系。比如当下系统使用的是sql server,为了未来切换其他db server时不至于每个调用的地方都修改,就要使用工厂来创建sql server模块。
然后,以个人理解,ioc可以有效地替换工厂。 不论如何,先记录一下代码的实例。
class Hero {
constructor(public point: [number, number]) {}
}
const entities = [];
const entityFactory = <
T extends {
new (...args: any[]): any;
}
>(
classToCreate: T,
numberOf: number,
...args: ConstructorParameters<T>
): InstanceType<T>[] =>
[...Array(numberOf)].map(() => new classToCreate(...args));
entities.push(...entityFactory(Hero, 10, [12, 10]));
六:never的使用
利用never与其他任何类型都不兼容的特性(除了never外,没有值可以赋给never,包括any),以控制代码在编译时就报错。
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
interface Triangle {
kind: "triangle";
whatever: number;
}
type Shape = Square | Rectangle | Circle | Triangle;
function assertNever(x: never): never {
throw new Error("Unexpected object: " + x);
}
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size;
case "rectangle":
return s.height * s.width;
case "circle":
return Math.PI * s.radius ** 2;
default:
return assertNever(s); // Error
// Argument of type ‘Triangle‘ not assignable to param of type ‘never‘
}
}
七:断言(Assert)
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg);
}
}
function yell(str) {
assert(typeof str === "string");
return str.toUppercase();
// ~~~~~~~~~~~
// error: Property ‘toUppercase‘ does not exist on type ‘string‘.
// Did you mean ‘toUpperCase‘?
}
参考:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html
https://github.com/David-Else/modern-typescript-with-examples-cheat-sheet