TypeScript入门学习笔记

107 阅读4分钟

介绍

TypeScript 基于 Javascript 基础之上的编程语言,是 JavaScript 的超集,或者叫扩展集。所谓超集就是在JavaScript 原有的基础上多了一些扩展特性,多出来的其实是一套更强大的类型系统,以及对 ECMAScript的新特性支持,它最终会编译成原始的 JavaScript。

安装

安装typescript

npm i typescript -g

安装 ts-node 测试编译运行 ts

npm i ts-node -g

编译

TS 本身没有运行环境,需要将 TS 编译为 JS 然后执行,JS 的运行环境就是浏览器和 Node。

TypeScript 的类型检查只是编译时的类型检查,而不是运行时的类型检查。一旦代码编译为 JavaScript,运行时就不再检查类型了。

ts的作用

  1. 编写一些公用方法和全局配置对象,用于提醒使用者别传错参数或者参数的值
  2. 编写组件的时候用于提示使用者有没有写错props
  3. 一些第三方库如果是ts编写,可以检测到使用者有没有调错方法,写错配置

总结

ts的最大意义就是避免写错、漏写,屏蔽掉一些低级错误。

1. typeScript 的特性有哪些?

  • 类型批注
  • 类型推断
  • 类型擦除
  • 接口
  • 枚举
  • mixin
  • 泛型编程
  • 名字空间
  • 元组

类型批注

使用 :类型的形式来标注类型。

function add(a: number, b:number):number {
    return a + b
}

add(1, 2)

基本类型批注: number bool string any

类型推断

    // 初始化 类型->string 
    let str = 'Hello,world';
    str = 1 // error

接口

描述对象类型 数据类型 number null string

interface User {
    name: string
    age: number
}

let user: User = {
    name: '张三',
    age: 18
} 

区别

  • TS是js的超集 扩展了js语法
  • 只对ts代码进行编译
  • .ts .tsx .dts

2. typeScript的数据类型有哪些?

  • boolean
  • number
  • string
  • array
  • tuple 元组
  • enum 枚举
  • any
  • null undefined
  • void 类型
  • never 类型 bottom lervel
  • object 类型

boolean

   let flag: boolean = true;
   flag = false

number

   let num: number = 1;
   num = '2' // wrong

string

   let str: string = 'hello';
   let world = 'world';
   let message = `hello,${world}`

any

   let name: any = '1231';

array

    let arr: string[] = ['1', '2', 3];
    let number: number[] = [1, 2, 3];

tuple

    let tupleArr: [number, string, boolean] = [1, '2', false];

enum

    enum Size {
        big,
        middle,
        small,
    }
    
    let a: Size = Size.big

null undefined

null undefined 所有类型的子类型

    let num: number | undefined
    num = 1

void

空类型 方法没有返回值

    function get(): void {
        console.log('no return value')
    }

never

任何类型的子类型 代表不会出现的值

    let a: never;
    a = 1 // wrong
    
    a = (() => {
        throw new Error('wrong)
    })()

object

对象类型 {}

    let obj: Object;
    obj = { name: '张三', age: 18 }

总结

  • 基本类型 增加了 void any enum never
  • 引用类型

3. 说说对Ts中高级类型的理解?有哪些?

高级类型

  • 交叉类型
  • 联合类型
  • 类型别名
  • 类型索引
  • 类型约束
  • 映射类型
  • 条件类型

交叉类型

通过&将多个类型合并为一个类型 是一个的操作

T & U

function extend<T, U>(first: T, second: U): T&U {
    let result: <T&U> = {};
    
    for(let key in first) {
        result[key] = first[key]
    }
    
     for(let key in second) {
        if (!result.hasOwnProperty(key)) {
            result[key] = second[key]
        }
    }
    return result; 
}

联合类型

通过 | 实现,是一个的意思

多个类型中的任意一个

T | U

number| string | boolean 只能有一个,不能共存

    function formatCommandline(command: string[] | string) {
        let line = '';
        if(typeof command === 'string') {
            line = command.trim();
        } else {
            line = command.join(' ').trim()
        }
    }

类型别名

通过type来定义 type SomeName = somexxx;

    type some = boolean | string;
    
    const a: some = true; // ok
    const b: some = '张三'; //ok
    const c: some = 1; //wrong

类型索引

keyof 类似 Object.keys

    interface Button {
        type: string
        text: string
    }
    
    type ButtonKeys = keyof Buttonm // 'type' | 'text'

类型约束

通过 extends 来实现类型约束

    type BaseType = string | number | boolean
    
    // 对copy的参数进行类型约束
    function copy<T extends BaseType>(arg: T): T {
        return arg;
    }
    
    copy({}) // wrong
    copy(1);
    copy('zzz');
    copy(true);
      

类型约束和类型索引一起使用

    function getValue<T, K extends keyof T>(obj: T, key: K): T[k] {
        return obj[key]
    }

类型映射

通过in 实现

    type Readonly<T> = {
        readonly [P in keyof T]: T[P]
    }
    interface Obj {
        a: string;
        b: string
    }
    
    type ReadOnlyObj = Readonly<obj>;
    /**
         {
            readonly a: string;
            readonly b: string;
        }
    */
   

条件类型

T extends U ? X : Y

3. ts中接口的理解?应用场景?

接口:方法特征的集合 interface

    interface Person {
        name: string;
        age?: number;
        readonly isMale: boolean;
        say: (words: string) => string;
        [propsName: string]: any // 对当前接口的拓展
    }
    // 继承接口 extends
    interface Fater {
        color: string
    }
    interface Mother {
        height: number
    }
    interface Son extends Father, Mother {
        name: string;
        height: number;
    }

应用场景

     interface IUser {
         name: string;
         age: number
     }
     
     const getUserInfo = (user: IUser): string => {
         return `name: ${user.name}, age: ${user.age}`
     }
     
     getUserInfo({name: '张三', age: '18'})

4. TS类

class OOP

类 是一种用户定义的引用类型

    class Car {
        engine: string;
        
        constructor(engine: string) {
            this.enghine = engine;
        }
        
        post(): void {
            console.log(`引擎`, this.engine);
        }
    }
    
    // 子类
    class DrameCar extends Car {
        post(): void {
            super.post();
            console.log(`dreameCar post`)
        }
    }

5. TS 修饰符

  • pubilic: 可以自由访问类中定义的内容
  • private: 只能在类的内部进行访问
  • protect: 除了可以在该类内部访问,还可以在子类中访问
    class Father {
        private name: string;
        constructor(name: string) {
            this.name = name
        }
    }
    
    const father = new Father('someone')
    father.name // wrong
    
    class Mother {
        protected name: string;
        constructor(name: string) {
            this.name = name;
        }
    }
    
    class Son extends Mother {
        say() {
            console.log(this.name)
        }
    }

6. TS 抽象类 & 使用技巧

抽象类能够作为其他派生类的基类去使用,抽象类一般不会直接被实例化

abstract

    abstract class Animal {
        abstract: song(); void;
        move(): void {
            console.log('move');
        }
    }
    
    class Cat extends Animal {
        song() {
            console.log('miaomiao~')
        }
    }
    
    const cat = new Cat();
    cat.song();
    cat.move();

补充

type 和 interface 区别

相同点:

1.type 和 interface 都可以描述对象和函数

    // 定义对象
    type Point= {
        x: number;
        y: number;
    };
    // 定义方法
    type SetPoint = (x: number, y: number) => void;
    
    // 定义对象
    interface Point {
        x: number;
        y: number;
    }
    // 定义方法
    interface SetPoint {
        (x: number, y: number): void;
    }
  1. 类型别名(type) 和 接口(interface)都支持扩展
    type Animal = {
        name: strng;
    };
    // 通过 & 拓展已定义的接口类型
    type Bear = Animal & {
        honey: boolean;
    }
    
    interface Animal {
        name: string;
    }
    // 通过 extends 拓展
    interface Bear extends Animal {
        honey: boolean;
    }
    
    const bear: Bear = getBear();
    bear.name
    bear.honey

不同点:

  1. 同名的interface会自动合并,而type不会
    interface User {
        name: string;
    }
    interface User {
        id: number;
    }
    
    let user: User = {
        id: 666,
        name: '张三'
    }
    user.id; // 666
    user.name; // '张三'

    type User = {
        name: string;
    };
    // wrong 标识符"User"重复, ts(2300)
    type User = {
        id: number;
    };
  1. type 可以为基本类型、联合类型或元组类型定义别名,而接口不行
    type MyNumber = number; // 基本类型
    type StringOrNumber = string | number; // 联合类型
    type MyTuple = [number, string, number]; // 元组

类型别名(type) 和 接口(interface)的一些使用场景

使用类型别名的场景:

  • 定义基本类型的别名时,使用 type
  • 定义元组类型时,使用 type
  • 定义函数类型时,使用 type
  • 定义联合类型时,使用 type
  • 定义映射类型时,使用 type

使用接口的场景:

  • 需要利用接口自动合并特性的时候,使用 interface
  • 定义对象类型且无需使用 type 的时候, 使用 interface