入门TypeScript:javaScript超集语言

本文介绍了TypeScript,一种JavaScript的超集语言,它提供了类型系统和ES6语法支持。通过TypeScript编译器,开发者可以将TS代码转换成JS代码。文章对比了Flow和TypeScript的区别,并详细讲解了如何使用TypeScript,包括安装、配置tsconfig.json文件,以及如何编写和编译TS代码。此外,还探讨了TS中的数据类型、类、继承、访问修饰符、接口等核心概念。
摘要由CSDN通过智能技术生成

前言

在之前我们已经了解了javaScript语言特征(类型),了解了静态类型有不少优点,合理运用可以让我们项目更加稳定健壮。

也入门了Flow(js类型检查工具)

这篇博客介绍下如何使用TypeScript(JavaScript超集语言)。

TypeScript是什么

TypeScript是微软公司开发的一款开源的JavaScript超集语言!

JavaScript超集: 当前任何JavaScript都是合法的TypeScript代码!

TypeScript主要为JavaScript提供了类型系统和ES6语法的支持!

TypeScript有自己的编译工具,我们写好的TypeScript代码最终会通过编译器编译成JavaScript代码进行运行!

Flow和TypeScript的区别

Flow是一个类型检查工具,TypeScript是一种开发语言!

如何使用

安装
TypeScript最终要运行起来,我们需要TypeScript代码转换成对应的JavaScript代码,那么TypeScript的命令行工具可以帮我们完成这件事情。
TypeScript的命令行工具安装方法(npm):

npm install -g typescript

安装好了之后,全局会提供一个tsc命令给我们使用!

编写ts代码

初体验

  • 新建一个index.ts文件
  • 写入简单例子
function hello(name:string){
	console.log(name);
}
hello('小明');
  • 执行编译
tsc ./index.ts
  • 编译结果
//同目录下生成了一个index.js文件
function hello(name) {
    console.log(name);
}
hello('小明');
  • 再改个参数试试
function hello(name:string){
    console.log(name);
}
hello(123);
  • 在执行编译
tsc ./index.ts

提示以下报错?
index.ts:4:7 - error TS2345: Argument of type '123' is not assignable to parameter of type 'string'.
4 hello(123);
        ~~~
Found 1 error.

但是一看index.js文件还是被编译过来了

function hello(name) {
    console.log(name);
}
hello(123);

我们发现

TypeScript 编译的时候即使报错了,还是会生成编译结果,我们仍然可以使用这个编译之后的文件。

如果要在报错的时候终止 js 文件的生成,可以在ts的配置文件: tsconfig.json 中配置 noEmitOnError 即可。
下面?就来介绍下ts的配置文件

tsconfig.json

创建配置文件

tsc --init

?常用配置项:

  • target: 指的就是将ts代码要转换成哪个版本的js代码 es5 es3
  • module: 指的就是将ts代码转换成js代码之后,使用的模块化的标准是什么
  • outDir: 指的就是将ts代码转换成js代码之后,js代码存放的文件夹路径
  • rootDir: 指的就是要将哪个目录中的ts代码进型转换,ts代码的存放路径
  • strict: 是否要将ts代码转换为严格模式的js代码!

使用配置文件

  • 不带任何输入文件的情况下调用tsc,编译器会从当前目录开始去查找tsconfig.json文件,逐级向上搜索父目录。
  • 不带任何输入文件的情况下调用tsc,且使用命令行参数–project(或-p)指定一个包含tsconfig.json文件的目录。
tsc -p ./tsconfig.json

ts中的数据类型

// number
let a: number = 10;
let b: number = NaN;
let c: number = Infinity;
let d: number = 0xA12;
let e: number = 0b1010101;
let f: number = 0o75;

// string
let str: string = "这是一个字符串"
let str1: string = '这是一个字符串'
let str2: string = `hello 这是一个模板字符串${a}`

// boolean
let flag: boolean = true;
let flag1: boolean = false;

// 数组
// Array<数据类型>
let arr: Array<number> = [1, 2, 3, 4];

// 数据类型[]
let arr1: number[] = [1, 2, 3, 4];


// 元组(Tuple)
let arr2: [number, string] = [1, 'a'];

arr2[0] = 'a';//error
arr2[0] = 1000;//work

arr2[2] = 'a';//work
arr2[2] = 1;//error
arr2[2] = [];//error

// void 空值
let res: void = undefined;

// undefined
// null
let res1: undefined = undefined;
let res2: null = null;

// any 表示任意类型
let somevar: any = 10;
somevar = "abc";
somevar = [];

// never类型
// never类型一般用在不可能返回内容的函数的返回值类型设置

function test(): never{
    while (true) {
        
    }
}
// object类型

// let o: object = {};
// let o1: object = [];

// 对象类型

let o: { name: string, age: number } = { name: "张学友", age: 18 };

// enum: 枚举类型

// gender: 0  1  -1

enum Gender{
    male = 1,
    female = 0,
    unknow = -1
}

let gender: Gender = Gender.male;

let obj = {
    gender: Gender.male
}

// 类型断言
//类型断言(Type Assertion)可以用来手动指定一个值的类型
//语法
/*<类型>值
或
值 as 类型*/
//例子:将一个联合类型的变量指定为一个更加具体的类型
function getLength(something: string | number): number {
    if (something.length) {
        return something.length;
    } else {
        return something.toString().length;
    }
}
//上例中,获取 something.length 的时候会报错。
//此时可以使用类型断言,将 something 断言成 string:
function getLength(something: string | number): number {
    if ((<string>something).length) {
        return (<string>something).length;
    } else {
        return something.toString().length;
    }
}

ts中的类

不太了解es6中的类的可以去看下这篇文章:简书:es6中class类的全方面理解(一)

class Person{
    // 和ES6不同的是,TS中属性必须声明,需要指定类型
    name: string
    // 声明好属性之后,属性必须赋值一个默认值或者在构造函数中进行初始化
    age: number
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    sayHello(msg: string): void {
        console.log(msg);
    }
}

ts中类的继承

class Animal{
    age: number
    constructor(age: number) {
        this.age = age;
    }
    eat() {
        console.log("吃个大鸡腿儿")
    }
}

class Dog extends Animal{
    type: string
    constructor(type: string, age: number) {
    //相当于es6中的call借用方法
        super(age);
        this.type = type;
    }
    // 子类中如果出现了和父类同名的方法,则会进行覆盖
    // 也就是调用的时候,调用的就是子类中的方法了!
    eat() {
        console.log('狗对象中的eat方法')
    }
}

var dog = new Dog("哈士奇", 18);
dog.eat();

ts类中的访问修饰符

// 访问修饰符:
// 指的就是可以在类的成员前通过添加关键字来设置当前成员的访问权限
// public: 公开的,默认   所有人都可以进行访问
// private: 私有的, 只能在当前类中进行访问
// protected: 受保护的,这能在当前类或者子类中进行访问
enum Color{
    red,
    yellow,
    blue
}

class Car{
    // 如果不加访问修饰符 则当前成员默认是公开的 所有人都可以访问的
    public color: Color
    constructor() {
        this.color = Color.red;
         this.run();//work
         this.loadPeople();//work
    }
    // 加了private之后,当前成员就只能在当前类中使用了!
    private run() {
        
    }
    // 加了protected之后,当前成员就只能在当前类或者子类中使用了!
    protected loadPeople() {
        
    }
}

let c1 = new Car();
 c1.color
 c1.run();//error
 c1.loadPeople();//error


class Audi extends Car{
    sayHi() {
        console.log(this.color)
         this.run();//error
         this.loadPeople();//work
    }
}
let audi = new Audi();
 audi.color;
 audi.run();//error

ts的只读属性和参数属性说明

class Cat{
    // 如果给属性添加了readonly修饰 则这个属性无法被赋值
    // 而且属性必须在声明的时候或者在构造函数中被赋值!
    readonly name: string
    // type: string
    // 构造函数中给参数前面加上修饰符,就相当于声明了一个属性!
    constructor(public type: string) {
        this.name = "加菲"
        // this.type = type
    }
}

var cat = new Cat("橘猫");
// cat.name = "123"
// cat.type;

ts中类成员的存取器

class People{
    // name: string = ""
    private _name: string = ""
    // 属性的存取器
    get name(): string{
        return this._name;
    }

    set name(value: string) {
        // 设置器中可以添加相关的校验逻辑
        if (value.length < 2 || value.length > 5) {
            throw new Error("名字不合法,不许使用!")
        }
        this._name = value;
    }
}

var p = new People();
p.name = "爱新觉罗PDD"

console.log(p.name);

ts中的接口(相当于一种规范)

interface

// 接口使用interface进行声明
interface AjaxOptions{
    url: string,
    // 给属性加上?之后,这个属性就是可选的!
    type?: string,
    data?: object,
    success(data: object): void
}


// option参数中 需要包含 url type data success
function ajax(options: AjaxOptions) {
    
}

ajax({
    url: "http://www.baidu.com",
    type: "get",
    data: {},
    success(data) {
        
    }
})

ts中的额外属性检查

interface Point{
    readonly x: number,
    y: number,
    [propName: string]: any
}

let poi: Point = {
    x: 10,
    y: 10
}

// poi.x = 100;

//传入额外属性z
let poi1: Point = {
    x: 10,
    y: 10,
    z: 100
}

函数类型的接口

interface SumInterFace{
    (a: number, b: number): number
}

let sum: SumInterFace = function (a: number, b: number) {
    return a + b;
}

类类型的接口

implements

interface PersonInterFace{
    name: string,
    age: number,
    eat():void
}

class XiaoMing implements PersonInterFace{
    name: string = "小明";
    age: number = 18;

    eat() {
        
    }
}

接口的继承

接口继承接口

interface TwoDPoint{
    x: number,
    y: number
}

interface ThreeDPoint{
    z: number
}

interface FourDPoint extends ThreeDPoint, TwoDPoint{
    time: Date
}

let poi2: FourDPoint = {
    z: 100,
    x: 100,
    y: 100,
    time: new Date()
}

接口继承类

class Bird{
    type: string = "画眉鸟"
    fly():void {
        
    }
}

interface Fly extends Bird{}

let flyingBird: Fly = {
    type: "啄木鸟",
    fly(): void {
        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值