读阮一峰《TypeScript 教程》
本文为读阮一峰《TypeScript 教程》后的一些个人笔记,原文章地址在: https://wangdoc.com/typescript/
1-basic 基本类型使用
function toStr(n: number): string {
return String(n);
}
function toString(num: number) {
return String(num);
}
var a = toString(2);
// any使用例子
let a1: any = "33";
a1 = null;
let b = 3;
b = a1;
// unknown类型,主要解决了any 类型污染其他变量的问题
let c: unknown = 1;
c = "3";
if (typeof c === "string") {
console.log("c: ", c.length);
}
// const interface o1 {
// foo: number
// }
let o: {} = { foo: 1 };
// console.log('foo: ', o.foo);
// 数组
const arr: (number | string)[] = [1, "1"];
const arr1: Array<number | string> = [1, "1"];
// 数组的类型推断 xxx
// 只读类型
const arr2: readonly number[] = [1, 2];
// 使用“const 断言”推断为只读数组
const arr3 = [1, 2] as const;
// 元组
type Turple = [number, any[]];
const t1: Turple = [1, [null, 3]];
const t2: typeof t1 = [1, ["null", 3]];
const a11: object = {};
console.log("a11: ", a11.foo);
2-functions&objects
// 通常的函数类型定义
type AddFunc = (a: number, b: number) => number
const add: AddFunc = (x, y) => x + y
// 简化的any
const add1: Function = (x: any, y: any) => x + y
// 这是一个很有用的技巧,任何需要类型的地方,都可以使用typeof运算符从一个值获取类型。
const subtraction: typeof add = (x, y) => x - y
// 箭头函数写类型
const subtraction1 = (x: number, y: number): number => x - y
// 可选参数 ?:
// 函数重载 ****
// 由于重载是一种比较复杂的类型声明方法,为了降低复杂性,一般来说,如果可以的话,应该优先使用联合类型替代函数重载。
3-interface
// interface 也可以用来声明对象
interface Obj {
x: number;
y: number;
}
// interface 也可以用来声明对象的方法:
interface Obj {
add(x: number, y: number): number;
}
interface Obj {
add2: (x: number, y: number) => number;
}
// interface 也可以用来声明独立的函数
interface Add {
(x: number, y: number): number;
}
// interface 继承 interface
// interface 继承 type
// interface 与 type 的区别有下面几点
// 1)type能够表示非对象类型,而interface只能表示对象类型(包括数组、函数等)。
// (2)interface可以继承其他类型,type不支持继承。
// so on
const foo: Obj = {
add: (x, y) => x + y,
add2: (x, y) => x + y,
x: 1,
y: 2,
};
console.log("foo: ", foo);
4-generics
// 泛型可以理解成一段类型逻辑,需要类型参数来表达。有了类型参数以后,可以在输入类型与输出类型之间,建立一一对应关系。
// 泛型
function getFirst<T>(arr: T[]): T {
return arr[0]
}
getFirst<number>([0, 1])
// 简写
// getFirst([0,1])
// 多类型参数
function map<T, U>(arr: T[], f: (args: T) => U): U[] {
return arr.map(f)
}
// 改写为箭头函数
const map2 = <T, U>(arr: T[], f: (args: T) => U): U[] => arr.map(f)
// 用法实例
map(
['1', '2', '3'],
(n) => parseInt(n)
);
map2(
['1', '2', '3'],
(n) => parseInt(n)
);
// 泛型主要用在四个场合:函数、接口、类和别名。
// 这个可以看 3-interface.ts的函数部分,
interface Fn {
<Type>(arg: Type): Type;
}
function id<Type>(arg: Type): Type {
return arg;
}
let myId: Fn = id;
// 类型参数的默认值 一般class用到
// 类型参数的约束条件
function comp<Type extends { length: number }>(a: Type, b: Type) {
if (a.length >= b.length) {
return a;
}
return b;
}
// 使用注意点
// 少用泛型。
// )类型参数需要出现两次。
5-as-Types
// TypeScript 一旦发现存在类型断言,就不再对该值进行类型推断,而是直接采用断言给出的类型。
// value as Type
// 正确
// const p1: { x: number } = { x: 0, y: 0 } as { x: number };
// 类型断言的条件
// 1.父子之间 2. unknown
// expr as unknown as T 这种可越过ts校验
const n = 2;
const str: string = n as unknown as string;
console.log(str.charAt(3));
// 非空断言(打开编译选项strictNullChecks时才有意义。如果不打开这个选项,编译器就不会检查某个变量是否可能为undefined或null。)
// x!.toFixed()编译就不会报错了。 非空断言在实际编程中很有用,有时可以省去一些额外的判断。
// 不过,非空断言会造成安全隐患,只有在确定一个表达式的值不为空时才能使用。比较保险的做法还是手动检查一下是否为空。
const root = document.getElementById("root");
// 报错
// eslint-
root!.addEventListener("click", () => {
/* ... */
});
function isString(value: any) {
if (typeof value !== "string") throw new Error("Not a string");
}
const aValue: string | number = 2;
isString(aValue);
console.log(aValue);
export interface A {
foo: string;
}
export const a = 123;
6-moduels
import type { A } from "./5-as-Types";
const b: A = { foo: '' }
console.log(b)
7-decorator
function simpleDecorator(
value:any,
context:any
) {
console.log(`hi, this is ${context.kind} ${context.name}`);
return value;
}
@simpleDecorator
class A {} // "hi, this is class A"
8-declare
// 举例来说,自己的脚本使用外部库定义的函数,编译器会因为不知道外部函数的类型定义而报错,这时就可以在自己的脚本里面使用declare关键字,告诉编译器外部函数的类型。
// document.title = '121'
Tags: