跳转到内容
aswind7
GitHub
Blog

读阮一峰《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'