typescript详解

typescript


前言

ts基础内容。


一、什么是TS?它和JS有何不同?

A 对比原理

他是JavaScript的一个超集,在原有的语法基础上,添加了可选的静态类型和基于类的面向对象编程。

面向项目

TS:面向于解决大型复杂项目中,架构以及代码维护复杂场景
JS:脚本话语言,用于面向单一场景

自主检测

TS:编译期间,主动发现并纠正错误
JS:运行时报错

类型检测

TS:弱类型,支持对于动态和静态类型的检测
JS: 弱类型,无静态类型选项

运行流程

TS:依赖编译,依赖工程化体系
JS: 直接在浏览器中运行

复杂特性

TS:模块化、泛型、接口

B. 安装运行

npm install -g typescript
tsc -v //打印版本号
tsc test.ts // 编译ts文件
// .ts => .js => 浏览器执行环境

// 知识点:所有的类型检测和语法检测 => 编译时进行

二、TS基础类型与写法

  • boolean、string、number、array、null、undefined
// es
let isEnabled = true;
let class = 'myClass';
let classNum = 2;
let u = undefined;
let n = null;
let classArr = ['basic', 'execute']
// ts
let isEnabled: boolean = true;
let class: string = 'myClass';
let classNum: number = 2;
let u: undefined = undefined;
let n: null = null;
let classArr: string[] = ['basic', 'execute']
let classArr: Array<string> = ['basic', 'execute']
  • tuple - 元组
// ts
let tupleType: [string, boolean];
tupleType = ['myClass', true];
  • enum - 枚举
// 数字类枚举 - 默认从零开始,从上到下依次递增
enum Score {
    BAD, // 0
    NG, // 1
    GOOD, // 2
    PERFECT // 3
}
let sco: Score = Score.BAD; // 0
// 字符串类型枚举
enum Score {
    BAD = 'BAD',
    NG = 'NG',
    GOOD = 'GOOD',
    PERFECT = 'PERFECT'
}
let sco: Score = Score.BAD; // 'BAD'
// 反向映射
enum Score {
    BAD, // 0
    NG, // 1
    GOOD, // 2
    PERFECT // 3
}
let scoName = Score[0]; // BAD
let scoVal = Score['BAD']; // 0
// 异构
enum Enum {
    A,  // 0
    B,  // 2
    C = 'C', // C
    D = 'D', // D
    E = 6,  //6
    F,  // 7   找上一个数字类型,然后递增,所以是 7 
}
// 知识点:指出异构的枚举值
// 知识点:手写将其转化为JS实现
let Enum;
(function(Enum) {
    // 正向
    Enum['A'] = 0;
    Enum['B'] = 1;
    Enum['C'] = 'C';
    Enum['D'] = 'D';
    Enum['E'] = 6;
    Enum['F'] = 7;
    // 反向
    Enum['0'] = 'A';
    Enum['1'] = 'B';
    Enum['6'] = 'E';
    Enum['7'] = 'F';    
})(Enum || (Enum = {}));
  • any unknown void
// any - 绕过所有类型检查 => 类型检测和编译筛查全部失效
let anyValue: any = 123;
anyValue = 'anyValue'; // 赋值为字符串
anyValue = false; // 赋值为布尔
let value1: boolean = anyValue; // 赋值给别的变量

// unknown - 绕过了赋值检查 => 禁止更改传递
let unknownValue: unknown;
unknownValue = true;
unknownValue = 123;
unknownValue = 'unknownValue';
let value1: unknown = unknownValue;// ok
let value2: any = unknownValue; // ok
let value3: boolean = unknownValue; // nok

// void - 声明函数的返回值  未 return;
function voidFunction(): void {
    console.log('void function')
}
// never - 函数永不返回
function error(msg: string): never {
    throw new Error(msg)
}
function longlongLoop(): never {
    while(true) {}
}
  • object / {} - 对象

接口 - interface

对行为的一种抽象,不代表任何业务逻辑,也没有任何值,具体行为由具体类实现
interface Class {
    name: string;
    time: number;
}
let myClass: Class = {
    name: 'ts',
    time: 2
}
// 只读 & 任意
interface Class {
    readonly name: string;
    time: number;
}
// 知识点 - readonly 和 JS 的引用是不同的 < = > const => 执行阶段不同
let arr: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = arr;
ro[0] = 12;
ro.push(5);
ro.length = 100;
arr = ro;
// 以上全部报错ERROR; const 修改指针对应的值是允许的,readonly是不允许修改任意值的。

// 任意
interface Class {
    readonly name: string;
    time: number;
    [propName: string]: any;
}
const c1 = {name:'JS', time: 1}
const c2 = {name: 'browser', time: 1}
const c3 = {name: 'TS', level: 1, time: 2}

交叉类型

// 合并
interface A {x: D}
interface B {x: E}
interface C {x: F}

interface D {d: boolean}
interface E {e: string}
interface F {f: number}

type ABC = A & B & C;
let abc: ABC = {
    x: {
        d: false,
        e: 'myClass',
        f: 5    
    }
}
// 合并冲突
interface A {
    c: string,
    d: string
}
interface B {
    c: number,
    e: string
}
type AB = A & B;
let ab: AB = {
    d: 'class',
    e: 'clcass'
}
 // => 且关系 => c: never
 // 合并时需要注意丢失参数的风险

断言 - 类型声明和转换 (开发者和编译器的告知交流)

编译状态在产生作用
// 尖括号 的形式做阶段性的类型声明
let anyValue: any = 'hi myClass';
let anyLength: number = (<string>anyValue).length;

// as声明
let anyValue: any = 'hi myClass';
let anyLength: number = (anyValue as string).length;
// 非空 ! - 只判断不为空
type ClassTime = () => number;
const start = (classTime: ClassTime | undefined) => {
    let num = classTime!();// 具体类型待定,但是非空是确认的
}
// 使用场景  通用中台处理逻辑
const tsClass: number | undefined = undefined;
const myClass: number = tsClass!;
    // 底层实现后,上层应用
    const tsClass = undefined;
    const myClass= tsClass; // undefined
    //肯定化保证
    let score: number;
    startClass();
    console.log(2 * score);
    function startClass() {
        score = 5;    
    }
    let score!: number; // 告知编译器,运行时会被赋值

类型守卫 - 保障语法规定的范围内,额外的确认

interface Teacher {
    name:string;
    courses: string[]
}
interface Student {
    name: string;
    startTime: Date;
}
type Class = Teacher | Student;
//in - 是否包含某种属性
functiong startCourse(cls: Class){
    if('courses' in cls){
            //老师
    }
    if('startTime' in cls){
            //学生
    } 
}
// typeof / instanceof - 类型分类场景下的身份确认
functiong startCourse(cls: Class){
    if(typeof cls.score === 'number'){
            //老师
    }
    if(typeof cls.score === 'string'){
            //学生
    } 
}
functiong startCourse(cls: Class){
    if(cls instanceof Teacher){
            //老师
    }
    if(cls instanceof Student){
            //学生
    } 
}
// 自定义类型
const isTeacher = function (cls: Teacher | Student): cls is Teacher {
    // 老师。。。
}
const getInfo = (cls: Teacher | Student) => {
    if(isTeacher(cls)){
        return cls.courses;    
    }
}

TS进阶方案

1.函数重载

class Class {
    start(name: number, score: number): number;
    start(name: string, score: string): string;
    start(name: string, score: number): number;
    start(name: Comnbinable, score: Comnbinable){
        if(typeof name ==='string' || typeof score ==='string'){
                    
        } 
        if(typeof name ==='number' || typeof score ==='number'){
                    
        } 
        if(typeof name ==='string' || typeof score ==='number'){
                    
        } 
    }
}

2.泛型-重用

function startClass <T, U>(name: T,score: U): T{
    //
}
function startClass <T, U>(name: T,score: U): string{
    //
}
function startClass <T, U>(name: T,score: U): T{
    return (name + String(score)) as any as T;
}

3.装饰器 - decorator

// 类装饰器
function myClass(target: Function):void {
    target.prototype.startClass = function(): void {
        // 逻辑    
    }
}
@myClass
class Course {
    constructor() {
        //业务逻辑    
    }
}
// 属性/方法装饰器
function nameWrapper(target: any, key: string): void {
    Object.defineProperty(target, key, {})
}
class Course {
    constructor() {
          // 业务逻辑  
    }
    @nameWrapper
    public name: string;
}

TS原理流程

// 1.源码
var a =3;

// 2.scanner扫描器生成令牌流
[
    'var': 'keyword',
    'a': 'identifier',
    '=': 'assignment',
    '3': 'imteger',
    ';': 'eos'
]

// 3. parser 解析器
{
    operation:'=',
    left: {
        keyword: 'var',
        right: 'a'    
    }
    right: '3'
}

// 4. binder 绑定器
// AST节点 node.symbol <=> 辅助校验器

// 5.1校验器checker
// ts节点语法检查 => 类型检查

// 5.2 发射器emitter
// 翻译完成每个node节点的内容,翻译成js => 输出

总结

以上就是今天要讲的内容,本文仅仅简单介绍了ts的原理和基本使用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值