TypeScript入门学习笔记


TypeScript入门学习笔记

typescript编译成为javascript,在编译时进行类型检查和代码转换,减少错误

ts=typescript,js=javascript

ts特性介绍

ts和js最大的区别就是ts多了类型注解功能, 通过名字中的"type"也能看出语言的重点在"类型"上. 这个类型分为基础类型高级类型, 高级类型就是通过基础类型组成的自定义类型.

基础类型

ts中包含了boolean / number(还支持2,8,16进制) / string / object / 数组 / 元组 / 枚举 / any / Undefined / Null / Void / Never

数组

// 方式1: 可以在元素类型后面接上 [],表示由此类型元素组成的一个数组
let list: number[] = [1, 2, 3];
// 方式2: 使用数组泛型,Array<元素类型>:
let list: Array = [1, 2, 3];

元组

元组类型允许表示一个已知元素数量类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 stringnumber 类型的元组。

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error

当访问一个越界的元素,会使用联合类型替代

x[3] = 'world';
x[6] = true; // Error, 布尔不是(string | number)类型

枚举

enum 类型是对 JavaScript 标准数据类型的一个补充。

enum Color {Red, Green, Blue}
let c: Color = Color.Green;
// 默认情况下,从0开始为元素编号, 也可以手动的指定成员的数值
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
// --------------生成的js代码-------------------------
var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
let c = Color.Green;

Any

不清楚具体啥类型(类型系统的顶级类型),不希望编译时检查,尽量

Unknow

Any类似,相同的是,任何类型的值都可以赋值给any/unknow类型的值,但是不同的是

  1. any类型的值可以赋值给任何类型
  2. unknow类型的值只能赋值给unknowany

Void

某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void

Nerver

值会永远不存在,即函数无限循环或者抛出异常导致函数不会执行return

高级类型

接口

大部分是对object的类型做更详细的标注,加上interface关键字

interface Article {
    title: string;
    count: number;
    content: string;
    tags: string[]; // 字符串数组
    category?: String; // 可选属性,就是多个 ?
    readonly uid:String;// 只读属性,一些对象属性只能在对象刚刚创建的时候修改其值
}

也可以定义一个类,能接口继承接口

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

函数类型

为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。

interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

非空断言

在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 ! 可以用于断言操作
对象是非 null 和非 undefined 类型。具体而言,x! 将从 x 值域中排除 null 和 undefined 。

let mayNullOrUndefinedOrString: null | undefined | string;
mayNullOrUndefinedOrString!.toString(); // ok
mayNullOrUndefinedOrString.toString(); // ts(2531)

确定赋值断言

允许在实例属性和变量声明后面放置一个 ! 号,从而告诉 TypeScript 该属性会被明确地赋值。

let x!: number;
initialize();
console.log(2 * x); // Ok

function initialize() {  x = 10; }

类型断言

有点点像强制类型转换。JSX中只能使用as来断言

let obj: any = "string";

let len1: number = (obj).length;
let len2: number = (obj as string).length;

console.log(len1+","+len2);

类型别名

类型别名可以表示很多接口表示不了的类型, 比如字面量类型(常用来校验取值范围)

type A = 'top'|'right'|'bottom'|'left'; // 表示值可能是其中的任意一个
type B = 1|2|3;
type C = '红'|'绿'|'黄';
type D = 150;

let a:A = 'none'; // 错误, A类型中没有'none'

类型推断

使用const声明的常量可以让TypeScript自动推断,无须再写类型注解

const x=1;  // 推断出x的类型是number

交叉类型

用于将多个接口类型合并成一个类型,从而实现等同接口继承效果

type IntersectionType = { id: number; name: string; } & { age: number };

函数

:number定义了返回类型 ?:可选参数,不传为undefined,...args收集剩下的参数

 function add(x: number, y: number,z?:number,...args:number[]): number { return x + y; };

泛型

声明一个类型变量,即对变量类型的抽象化

// 参数和返回值的类型相同
function identity(arg: T): T {
    return arg;
}

泛型类

class Person{
  name: T;
  constructor(name: T) {
    this.name = name;
  }
  say(str: T): string {
    return this.name + ":" + str;
  }
}
let xuan: Person = new Person('lxx');
console.log(xuan.say("nihao"));
//也可以不显示指定,ts会自动推断
let yuan = new Person('lyq')

泛型接口

interface Goods{
    id:number;
    title: string;
    size: T;
}
let apple:Goods = {id:1,title: '苹果', size: 'large'};
let shoes:Goods = {id:1,title: '苹果', size: 43};

关键字

工具类型

typeof 和keyof还不算是

typeof

typeof 的主要用途是在类型上下文中获取变量或者属性的类型

interface Person {
  name: string;
  age: number;
}
const sem: Person = { name: "semlinker", age: 30 };
type Sem = typeof sem; // type Sem = Person

keyof

获取某个类型的所有键,返回的是联合类型

interface Person {
  name: string;
  age: number;
}

type K1 = keyof Person; // "name" | "age"
let K2: keyof number; // let K2: "toString" | "toFixed" | ...

Partial

将类型的属性变成可选的(只支持一层,可以用DeepPartial)

type NewUserInfo = Partial;

Required

将类型的属性变成必选

Readonly

将类型的属性变成只读

Pick

将类型的属性挑选出来

type NewUserInfo = Pick;

ReturnType

用来得到一个函数的返回值类型(type)

type Func = (value: number) => string;
const foo: ReturnType = "xxx";

Exclude

从一个类型中移除一些类型

type T0 = Exclude<"a" | "b" | "c", "a">; // T0 = "b" | "c"

Extract

从一个类型中提取一些类型

type T0 = Extract<"a" | "b" | "c", "a" | "f">; // T0 = "a"

Omit

Omit 的作用是使用 T 类型中除了 K 类型的所有属性,来构造一个新的类型。

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Omit;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

NonNullable

用来过滤类型中的 nullundefined 类型。

type T0 = NonNullable; // string | number

Parameters

用于获得函数的参数类型组成的元组类型。

// [string, (number | undefined)?]
type C = Parameters;

Record

Record< k extends keyof any, T > 的作用是将 K 中所有的属性的值转化为 T 类型。

interface PageInfo {
  title: string;
}

type Page = "home" | "about" | "contact";

const x: Record = {
  about: { title: "about" },
  contact: { title: "contact" },
  home: { title: "home" },
};

ts安装及基本编写基本的代码

  1. 命令行:npm i -g typescript

  2. 编写代码,文件为hello.ts

    interface stu {
      id: number,
      name: string
    }
    let lyq: stu = { id: 1, name: "卢元庆" }
    
  3. 编译成js文件 命令行: tsc .\hello.ts 可以加上 -t es2020 生成es2020版本的js

    var lyq = { id: 1, name: "卢元庆" };
    
  4. 利用tsconfig.json对编译生成的js代码进行配置,比如生成目标js的版本为es6、删除注释

  5. 生成当前文件夹、项目的tsconfig.json 命令行 tsc --init

  6. tsc fileName 是没办法遵循tsconfig.js文件,直接tsc即可

使用官方提供的在线开发ts的云环境

https://www.typescriptlang.org/zh/play

参考文章:

[1]:https://juejin.im/post/6844904008583217165 - "为 Vue3 学点 TypeScript , 体验 TypeScript"
[2]:https://juejin.im/post/6844903929172459534 - "TypeScript 入门系列 | TypeScript 基础(一)"
[3]:https://juejin.im/post/6876240277208563720#comment - "技术胖的 TypeScript免费视频图文教程(2W字)"
[4]:https://juejin.im/post/6875091047752400910 - "细数 TS 中那些奇怪的符号"
[5]:https://juejin.im/post/687698135834689536 - "结合实例学习 Typescript"
[6]:https://juejin.im/post/6872111128135073806 - "一份不可多得的 TS 学习指南(1.8W字)"
[7]:https://juejin.cn/post/6844903902563794952 - "为 Vue3 学点 TypeScript, 解读高级类型"
[8]: https://juejin.cn/post/7018805943710253086 - "2021 typescript史上最强学习入门文章(2w字)"