TypeScript(一)

目录

一、TypeScript简介

二、TypeScript 开发环境搭建

2.1、下载安装

2.2、通过配置编译

2.3、常见配置

2.4、自动编译

三、基本类型

3.1、变量

3.2、类型声明

3.3、基础/基元类型

3.4、数组类型

3.5、对象类型

3.6、可选属性

3.7、null与unfined类型

3.8、enum 枚举

3.9、tuple元组

3.10、any(任何类型)

3.11、void(空值)

3.12、自动类型判断

3.13、类型别名和字符串字面量类型

3.14、联合类型-Union Type

3.15、函数

3.16、类型断言

四、接口(Interface)

五、类

5.1、属性和方法

5.2、类的继承

5.3、存取器

5.4、静态成员

5.5、完整语法

六、泛型

一、TypeScript简介

TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上TypeScript扩展了JavaScript的语法,解决了JavaScript的“痛点”:弱类型和没有命名空间,导致很难模块化。

  1. TypeScript是JavaScript的超集

  2. 它对JS进行了扩展,向JS中引入了类型的概念,并添加了许多新的特性。

  3. TS代码需要通过编译器编译为JS,然后再交由JS解析器执行

  4. TS完全兼容JS,换言之,任何的JS代码都可以直接当成JS使用。

  5. 相较于JS而言,TS拥有了静态类型,更加严格的语法,更强大的功能;TS可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS代码可以编译为任意版本的JS代码,可有效解决不同JS运行环境的兼容问题;同样的功能,TS的代码量要大于JS,但由于TS的代码结构更加清晰,变量类型更加明确,在后期代码的维护中TS却远远胜于JS。二、TypeScript 开发环境搭建

二、TypeScript 开发环境搭建

2.1、下载安装

  1. 下载Node.js

  2. 安装Node.js

  3. 使用npm全局安装typescript

    • 进入命令行

    • 输入:npm i -g typescript

    • tsc空格-v命令用来测试是否安装成功

  4. 创建一个ts文件

  5. 使用tsc对ts文件进行编译

    • 进入命令行

    • 进入ts文件所在目录

    • 执行命令:tsc xxx.ts

2.2、通过配置编译

每次写完ts文件都要输入一次命令是不是很麻烦呢,能不能保存文件时就自动编译运行ts文件呢

  • cd到项目下

  • 使用 tsc -init 会生成tsconfig.json 文件 ( tsconfig.json文件与TypeScript编译器(tsc)的配置相对应 是 TypeScript 使用 tsconfig.json 文件作为其配置文件 用来 指定待编译文件和定义编译选项。 )

  • 修改配置文件tsconfig.json, 在里面修改对应配置项: "target": "ES6"; "outDir": "./Js", //存放的文件地址; "strict": false;

  • 直接使用tsc命令即可编译【左上方的终端---》运行任务(第三项)----》显示所有任务----》监视tsconfig.json也可以实现实时运行TS文件】

2.3、常见配置

{
  "compilerOptions": {
    "target": "ES5",             // 目标语言的版本
    "module": "commonjs",        // 指定生成代码的模板标准
    "noImplicitAny": true,       // 不允许隐式的 any 类型
    "removeComments": true,      // 删除注释 
    "preserveConstEnums": true,  // 保留 const 和 enum 声明
    "sourceMap": true,            // 生成目标文件的sourceMap文件(简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便)
    "outDir":"./out/"           //编译输出的文件夹
  },
  "files": [   // 指定待编译文件(files 配置项值是一个数组,用来指定了待编译文件,即入口文件。入口文件依赖其他文件时,不需要将被依赖文件也指定到 files 中,因为编译器会自动将所有的依赖文件归纳为编译对象,即 index.ts 依赖 user.ts 时,不需要在 files 中指定 user.ts , user.ts 会自动纳入待编译文件。)
    "./src/index.ts"  
  ]
}

2.4、自动编译

命令自动编译

监控指定文件:tsc xxx.ts -w

监控全部文件: tsc -w

三、基本类型

3.1、变量

注意:let变量不能重复声明

注意:const它拥有与 let相同的作用域规则,但是不能对它们重新赋值。

注意:除了下划线 _ 和美元 $ 符号外,不能包含其他特殊字符,包括空格

3.2、类型声明

(1)通过类型声明可以指定TS中变量(参数、形参)的类型

(2)指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错

(3)简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值

(4)语法:

let 变量: 类型;
let 变量: 类型 = 值;
function fn(参数: 类型, 参数: 类型): 返回值类型{
    ...
}

3.3、基础/基元类型

类型例子描述
number1, -33, 2.5任意数字
string'hi', "hi", hi任意字符串
booleantrue、false布尔值true或false

3.4、数组类型

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];//泛型语法

3.5、对象类型

{}用来指定对象中可以包含哪些属性

语法:{属性: 属性值, 属性: 属性值...}

let obj:{name:string,age:number}={
    name:"xixi",
    age:18
}

注意:如果在使用对象的时候 必须给每个属性都要传入对应的值 否则会报错

// 没有给age传值就会报错
let obj:{name:string,age:number}={
    name:"xixi"
}

3.6、可选属性

在属性名后面加?,表示该属性是可选的

// age为可选属性 所以不传之也不会报错
let obj:{name:string,age?:number}={
    name:"xixi"
}

3.7、null与unfined类型

null是 定以不存在的

unfined 是未初始化的值

3.8、enum 枚举

TS中新增类型 使用枚举类型可以为一组数值赋予友好的名字。枚举表示的是一个命名元素的集合值

就是给一组数据起一个友好的名字

数字枚举类型和字符串枚举类型;

enum user{xiaoming,xiaohong,xiaobai}
console.log(user.xiaohong)//默认情况下数据的值从0开始

// 设置值
enum user{xiaoming,xiaohong=99,xiaobai}
console.log(user.xiaohong)
console.log(user.xiaobai)

// 字符串枚举设置值
enum user{xiaoming,xiaohong="小红",xiaobai="小白"}
console.log(user.xiaohong)
console.log(user.xiaobai)

enum NumberType {
    one = 2,//未赋值的话,第一个参数默认为0,后面递增
    two = 1,//后面的值如果没有手动赋值,会根据前面的值递增
    three,
    four
}
// 手动赋值注意:尽量不要写一些重复的值
输出的NumberType如下:
let obj = {
    '1': 'two',
    '2': 'three',    //three覆盖掉了one
    '3': 'four'
}

3.9、tuple元组

元组,TS新增类型,元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同(赋值的顺序不能变)

let arr:number[]=[1,2,3,4]
// 元祖(Tuple) 合并了不同类型的对象【一一对应】
let Tarr:[number,string]=[123,'123']
// 添加内容的时候,需要是number或者string类型
Tarr.push(456)
Tarr.push('345')
Tarr.push(true);//报错

3.10、any(任何类型)

在一些情况下,如果我们无法确定变量的类型时(或者无需确认类型时),我们可以将其指定为 any 类型。 TS中对于被标记为 any 类型的变量,是没有进行类型检查而直接通过编译阶段的检查(关闭了类型校验)。 在我们的系统中还是应当尽量避免使用 any 类型,以尽可能的保证系统健壮性。

let d: any = 4;
d = 'hello';
d = true;

3.11、void(空值)

一种类型,告诉你函数和方法在调用时不返回任何内容【表示没有任何返回值的函数】。

function fun(text:string,num:number=18):void{
    console.log(text+"---"+num)
}
fun("xixi")

3.12、自动类型判断

TS拥有自动的类型判断机制

当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型

所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明

3.13、类型别名和字符串字面量类型

类型别名用来给一个类型起个新名字,使用 type 创建类型别名,类型别名常用于联合类型。

在实际应用中,有些类型名字比较长或者难以记忆,重新命名是一个较好的解决方案

// 创建一个String别名
type xiaoming=String;
// 使用别名
let textCon:xiaoming="xixi";

console.log(textCon);//xixi
// 常用于给联合类型起别名
type all = string | number | boolean
let a: all = 123
a = ''
let b: all = true
b = 123
// 字符串字面量类型====》用来约束取值,只能是其中的一个
type stringType='张三丰'|'张三'|'张大炮'
let names:stringType='张三'

3.14、联合类型-Union Type

联合类型表示的值可能是多种不同类型当中的某一个联合类型放宽了类型的取值的范围,也就是说值的范围不再限于某个单一的数据类型同时,它也不是无限制地放宽取值的范围,如果那样的话,完全可以使用 any 代替。

// 给多个类型创建一个名字
type newType=String|Number;
// 可以在赋值的时候赋值字符串与数字
let demoText:newType="你好我可以创建字符串与number"

3.15、函数

(1)函数声明与函数表达式

// ts 函数声明,命名函数
function add(a: number, b: number): number {
    return a + b
}
// 两个参数都是number类型,:number表示函数的返回值也是number类型
console.log(add(1, 2));//3
let c: number = add(1, 2)
console.log(c);//3
// 函数表达式,匿名函数
let add2 = function (a: number, b: number): number {
    return a + b
}
console.log(add2(1, 2));

(2)可选参数和默认参数

let getName = function (x: string, y?: string): string {
    return x + y
}
// 可选参数? 必选参数不能位于可选参数后
console.log(getName('zx'));
let getName2 = function (x: string, y?: string, z: string = '你好'): string {
    return x + y + z
}
// 默认参数 可以放在必选参数以及可选参数后

(3)剩余参数和函数重载

// 剩余参数
function fn(x, y, ...args) {
    console.log(x, y, ...args);//[1,2,3,4]
}
fn('', '', 1, 2, 3, 4)
// 函数重载:函数名相同,形参不同的多个参数
// 数字 相加,字符串 拼接
function newAdd(x: string | number, y: string | number): string | number {
    if (typeof x == 'string' && typeof y == 'string') {
        return x + y;//字符串拼接
    } else if (typeof x == 'number' && typeof y == 'number') {
        return x + y;//数字相加
    }
}
console.log(newAdd(1, 2));//3
console.log(newAdd('1', '2'));//12
// 函数重载声明,可以使用重载定义多个newAdd的函数类型
function newAdd(x: string, y: string): string
function newAdd(x: number, y: number): number

3.16、类型断言

// 定义一个函数,获取到一个数字或者字符串的长度
// 类型断言:可以手动指定一个类型
// 2种方式
// 1、变量 as 类型
// 2、<类型>变量
// 作用一:将一个联合类型断言为其中一个类型
function getLength(x: string | number): number {
    if ((x as string).length) {
        return (<string>x).length
    } else {
        return x.toString().length
    }
}
console.log(getLength('123'));
console.log(getLength(123));
// 作用二:将任何一个类型断言为any,any类型是访问任何属性和方法的
(window as any).a = 10
// 作用三:将any断言为一个具体的类型
function abc(x:any,y:any):any{
    return x+y
}
let a=abc(1,2) as number//a--->数值类型
let b=abc(1,2) as string//b--->字符串类型

四、接口(Interface)

接口是定义对象类型的另外一种方式 ,在程序设计里面,接口起到一种限制和规范的作用

使用interface关键字定义 接口一般首字母大写 有的编程语言中会建议接口的名称加上 I 前缀示例(检查对象类型):

interface IUser{
    name:String,
    showname():void
}

接口使用:使用:号接口名来进行使用 注意:定义的变量比接口少了一些属性是不允许的,多一些属性也是不允许的。赋值的时候,变量的形状必须和接口的形状保持一致。

interface IUser{
    name:String,
    showname():void
}
let user:IUser={
    name:"xixi",
    showname(){
        console.log(`名字是${this.name}`)
    }
}
console.log(user.name)
user.showname()

五、类

5.1、属性和方法

// 实例化对象
class Person{
    name:string
    age:number
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
    sayHi(str:string){
        console.log('hi,'+str);//hi,李四
    }
}
// new的时候,会执行类中的构造方法
let p=new Person('张三',18)
p.sayHi('李四')

5.2、类的继承

class Animal {//父类
    name: string
    age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
    sayHi(str: string) {
        console.log('hi,' + str);//hi,李四
    }
}
class Dog extends Animal {//子类
    constructor(name: string, age: number) {
        super(name, age)//使用super调用父类的构造函数
    }
    //可以调用父类的方法,还可以重写父类的方法
    sayHi() {
        console.log("自己的方法");
        super.sayHi("狗")
    }
}
const a = new Animal('猫', 3)
a.sayHi('猫')
const d = new Dog('狗', 2)
d.sayHi()
// 总结:类与类之间存在继承关系,通过extends进行继承
// 子类可以调用父类的方法,通过super
// 子类还可以重写父类的方法

5.3、存取器

存取器:可以帮助我们控制对对象成员的访问

class Name {//父类
    firstName: string
    lastName: string
    constructor(firstName: string, lastName: string) {
        this.firstName = firstName
        this.lastName = lastName
    }
    // 设置存取器
    // 读取器--》读取数据
    get fullName() {
        return this.firstName + '-' + this.lastName
    }
    // 设置器--》设置数据
    set fullName(val) {
        let names = val.split('-')
        this.firstName = names[0]
        this.lastName = names[1]
    }
}
const n = new Name('张', '三')
console.log(n.fullName);//张-三
n.fullName = '李-四'

5.4、静态成员

// 静态属性 只属于自己的属性和方法
class A {
    static name1: string
    static sayHi() {
        console.log("hi");
    }
}
const a1 = new A()
console.log(A.name1);
A.sayHi()
a1.name//报错

5.5、完整语法

参考博客:TypeScript 语法_typescript 往后加n天-CSDN博客

六、泛型

在开发的时候我们需要考虑我们的代码有非常好的重用性(我们开发的模块 不仅仅能支持当前的数据类型 同时也要支持未来不确定的数据类型

那么在这个时候就可以使用泛型来创建可以重用的组件功能 这样一来我们的组件就可以根据后续的需要 来接收任意的类型

什么是泛型?

就是把不能明确的类型 变成一个参数(就是一个类型变量--用来存储类型的变量

泛型通常用字母T来表示(不一定必须是T 可以是任何的单词

// 下面这个 函数定义了一个T的泛型 那么这个函数就可以接受传递进来的任意类型
function fun<T>(name:T):T{
    return name
}

console.log(fun<number>(123))//传递number类型
console.log(fun<string>("你好"))//传递string类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值