阅读 563

TypeScript的应用及方法介绍(typescript菜鸟教程)

TypeScript是JavaScript的一种超集是一种强类型语言

原始类型 < Primitive Type >

原始数据类型
const a: string = 'foobar'

const b: number = 123 //NaN Infinity

const c: boolean = true //false

// 在非严格模式(strictNullChecks)下,
// string,number,boolean都可以为空
// const d: string = null
// const d: number = null
// const d: boolean = null

const e: void = undefined

const f: null = null

const g: undefined = undefined

// Symbol 是 ES2015 标准中定义的成员
// 使用它的前提是必须确保有对应的 ES2015 标准库的引用
// 也就是 tsconfig.json 中的 lib 选项必须包含 ES2015
const h: symbol = Symbol()复制代码

作用域问题

1.使用立即执行函数

(function(){
    const a = 123
})()复制代码

2.export {}

const a = 123 
export {}复制代码

Object Types<对象类型>

指的是除原始类型之外的类型,可以使用对象自变量的语法方式

   const foo: object = function(){}//[] {}
   const obj: { foo: number, bar: string } = { foo: 123, bar: 'strinf'}

   Array Types

   const arr1: Array<number> = [1, 2, 3]

   const arr2: number[] = [1, 2, 3]

   function sum(...args:number[]){
       // 判断是不是每个成员都是数字
       return args.reduce((prev,current)=>prev+current,0)
   }
   sum([1,2,3])//6复制代码

Tuple Types<元组类型>

指的是明确元素类型元素数量的一个数组

const tuple: [number, string]  = [24,'shy']

const age = tuple[0]
const name = tuple[1]

const [age,num] = tuple

Object.entries({
    foo:123,
    bar:456
})复制代码

Enum Types <枚举类型>

特点:

1.给一组数值分别取上不同的名字

2.一个枚举中只会存在几个固定的值,并不会出现超出范围的可能性

可以使用object模仿枚举类型
const PostStatus = {
    Draft: 0,
    Unpublished: 1,
    Published: 2
}
typeScript中使用enum去定义一个枚举值
enum PostStatus = {
    Draft = 0,
    Unpublished = 1,
    Published = 2
}
如果不设置初始值的话默认从0开始依次赋值
enum PostStatus = {
    Draft,
    Unpublished,
    Published
}
如果枚举值是字符串,需要设置初始值
enum PostStatus = {
    Draft = 'aaa',
    Unpublished = 'bbb',
    Published = 'ccc'
}复制代码

枚举类型会入侵到运行时候的代码(会影响编译后的结果)

以枚举为数字类型为例 转译为js文件时

var PostStatus;
(function (PostStatus){
    PostStatus[PostStatus['Draft'] = 0] = 'Draft'
    PostStatus[PostStatus['Unpublished'] = 1] = 'Unpublished'
    PostStatus[PostStatus['Published'] = 2] = 'Published'
})(PostStatus||(PostStatus={}))
使用常量枚举就会解决这个问题(在enum前加上const)
 const enum PostStatus = {
    Draft,
    Unpublished,
    Published
}复制代码

Function Types<函数类型>

声明型函数类型限制
function func1(a: number,b: number): string{
    return 'funct1'
}
调用是必须传入两个number类型的值,少或多都会造成异常
当传入参数为可选参数时可以使用?的形式,但需要注意可选参数要放在最后
function func1(a: number,b?: number): string{
    return 'funct1'
}
也可以使用给参数设置默认值
function func1(a: number,b: number = 10): string{
    return 'funct1'
}
使用任意个数参数
function func1(...rest: number[]): string{
    return 'funct1'
}
函数表达式类型限制
   const func2:(a: number,b: number = 10) => string =  function(a: number,b: number): string{
    return 'funct2'
}复制代码

Any Types<任意类型>

不会进行类型检查,所以类型是不安全的

function stringify(value){
    return JSON.stringify(value)
}

stringify('string')

stringify(123)

stringify(true)

let foo: any = 'string'

foo = 100复制代码

Type Inference<隐式类型推断>

根据变量的使用情况推断类型

let age = 18 //number

age = 'string' //age会报语法错误

当不设置初始值时,默认类型为any

建议为每个变量添加明确的类型,便于维护,理解复制代码

Type assertions<类型断言>

明确知道类型时

//假定这个nums来自一个明确的接口
const nums = [100,120,1320,130]

const res = nums.find(i=>i>0)

const square = res * res //res为number||undefined
在这种情况下我们需要明确res为number类型复制代码

使用类型断言的两种方式

1.as 
const num1 = res as number

2.<number>
const num2 = <number>res //JSX 下不能使用,会和标签冲突

类型断言(代码在编辑阶段的概念)不是类型转换(代码在运行阶段的概念)复制代码

Interfaces<接口>

一种规范,一种约定

interface Post{
    title: string; //结尾可以使用,;或不写
    contet: string;
}

function printPost(post: Post) {
    console.log(post.title)
    console.log(post.contet)
}

printPost({
    title: 'Hello TypeScript',
    content: 'A JavaSctipt superset'
})复制代码

总结:接口就是用来约束对象结构,一个对象要实现接口,他就必须要拥有接口中约束的所有成员

可选成员
interface Post{
    title: string; //结尾可以使用,;或不写
    contet: string;
    subTitle?: string //使用?表示为可选成员
}
只读成员
interface Post{
    title: string; //结尾可以使用,;或不写
    contet: string;
    readonly summary: string//只读成员,不能修改
}
动态成员
interface Cache{
    [key: string]: string //成员键与值都为字符串类型
}

const cache: Cache = {}

cache.foo = 'value1'
cache.bar = 'value2'复制代码

Classes<类>

描述一类具体事物的抽象特征

class Person {
    name: string
    age: number

    constructor(name: string, age: number){
        this.name = name
        this.age = age
    }

    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`)
    }
}
private私有属性,只能内部访问
class Person {
    name: string
    private age: number

    constructor(name: string, age: number){
        this.name = name
        this.age = age
    }

    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`)
        console.log(this.age)
    }
}
const tom = new Person('tom',18)
只能访问到tom.name,不能访问到tom.age
public公有属性,默认就是public
protected 也是私有属性,只允许在子类中显示
class Person {
    name: string
    private age: number
    protected gender:boolean

    constructor(name: string, age: number){
        this.name = name
        this.age = age
        this.gender = true
    }

    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`)
        console.log(this.age)
    }
}
class Student extends Person{
    constructor(name: string, age: number){
        super(name,age)
        console.log(this.gender)
    }
}复制代码

接口:约束子类当中必须拥有某个成员(只是接口的抽象,不包含实现)

interface Eat{
    eat(food: string): void //只做接口约定不做接口实现
}
interface Run{
    run(distance: string): void //一个接口约束一个能力,一个类型实现多个接口
}

class Person implements Eat,Run {
    eat(food: string): void {
        console.log(`${food}`)
    }
    run(distance: string): void {
        console.log(`${distance}`)
    }
}复制代码

抽象类

抽象类:约束子类当中必须拥有某个成员(包含接口实现)

abstract class Animal {
    eat(food: string): void {
        console.log(`${food}`)
    }
    abstract  run(distance: string): void {
        console.log(`${distance}`)
    }
}
只能继承不能new创建

class Dog extends Animal{
    run(distance: string): void {
        console.log(`${distance}`)
    }
}

const d = new Dog()
d.eat('肉')
d.run('跑')复制代码

泛型

在定义函数接口或类时没有指定具体类型,在使用时再去指定类型的特征

function createArray<T> (length: number, value: T):T {
    const arr = Array<T>(length).fill(value)
    return arr
}

const res = createArray<string>(3,'str')//['str','str','str']
const res2 = createArray<number>(3,100)//[100,100,100]复制代码

TypeScript的优缺点

优点

  1. 增强了代码的可读性和可维护性

  2. 包容性,js可以直接改成ts,ts编译报错也可以生成js文件,兼容第三方库,即使不是ts编写的

  3. 社区活跃,完全支持es6

缺点

  1. 增加学习成本

  2. 增加开发成本,因为增加了类型定义

  3. 需要编译,类型检查会增加编译时长,语法和类型系统复杂的话时间特别特别长

  4. eval和new Function()这种操作类型系统管不到

  5. 和有些库结合时不是很完美


作者:菜市场小石
链接:https://juejin.cn/post/7039337621364932621

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐