TS基础语法

简介

  • 静态类型语言:在编译阶段确定所有变量的类型
  • 动态类型语言:在执行阶段确定所有变量的类型
  • TypeScript是JavaScript的超集,它对JS进行了扩展,向JS中引入了类型的概念,并添加了许多新的特性。
  • TS代码需要通过编译器编译为JS,然后再交由JS解析器执行。
  • TS完全兼容JS,换言之,任何的JS代码都可以直接当成JS使用。
  • 相较于JS而言,TS拥有了静态类型,更加严格的语法,更强大的功能;TS可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS代码可以编译为任意版本的JS代码,可有效解决不同JS运行环境的兼容问题;同样的功能,TS的代码量要大于JS,但由于TS的代码结构更加清晰,变量类型更加明确,在后期代码的维护中TS却远远胜于JS。

安装

  • 使用npm全局安装typescript npm i -g typescript
  • 创建一个ts文件,使用tsc对ts文件进行编译,执行命令:tsc xxx.ts

配置

  1. tsc --init 生成 tsconfig.json 配置文件,tsconfig.json 可以写注释
  2. tsconfig.json 中的一些配置属性
  • include 用来指定哪些ts文件需要被编译,路径:** 表示任意目录,* 表示任意文件
  • exclude 不需要被编译的文件目录,默认值:["node_modules", "bower_components", "jspm_packages"]
  • compilerOptions 编译器的选项
  • noImplicitThis 不允许不明确类型的this
function fn2(this: Window){
    alert(this);
}
  • strictNullChecks 严格的检查空值
let box1 = document.getElementById('box1');

// if(box1 !== null){
//     box1.addEventListener('click', function (){
//         alert('hello');
//     });
// }
// 添加问号 box1存在的情况下才可以调用addEventListener方法
box1?.addEventListener('click', function (){
    alert('hello');
});


{
/*
  tsconfig.json是ts编译器的配置文件,ts编译器可以根据它的信息来对代码进行编译
    "include" 用来指定哪些ts文件需要被编译
      路径:** 表示任意目录
            * 表示任意文件
    "exclude" 不需要被编译的文件目录
        默认值:["node_modules", "bower_components", "jspm_packages"]
*/

  "include": [
    "./src/**/*"
  ],
  "exclude": [
    "./src/hello/**/*"
  ]

   // compilerOptions 编译器的选项
  "compilerOptions": {
    // target 用来指定ts被编译为的ES的版本
    "target": "es2015",
    // module 指定要使用的模块化的规范
    "module": "es2015",
    // lib用来指定项目中要使用的库
    "lib": ["es6", "dom"]
    // outDir 用来指定编译后文件所在的目录
    "outDir": "./dist",

    // 将代码合并为一个文件
    // 设置outFile后,所有的全局作用域中的代码会合并到同一个文件中
    //"outFile": "./dist/app.js"

    // 是否对js文件进行编译,默认是false
    // "allowJs": true,
    // 是否检查js代码是否符合语法规范,默认是false
    //  "checkJs": true,

    // 是否移除注释
    "removeComments": true,
    // 不生成编译后的文件
    "noEmit": false,
    // 当有错误时不生成编译后的文件
    "noEmitOnError": true,
    // 所有严格检查的总开关
    "strict": true,
    // 用来设置编译后的文件是否使用严格模式,默认false
    "alwaysStrict": true,
    // 不允许隐式的any类型
    "noImplicitAny": true,
    // 不允许不明确类型的this
    "noImplicitThis": true,
    // 严格的检查空值
    "strictNullChecks": true
  }
}

类型

基本类型

  • boolean
  • number
  • string
  • array
  • 元组类型(tuple)
  • 枚举类型(enum)
  • 任意类型(any)
  • null
  • undefined
  • object
  • void
  • never

高级类型

  • union 组合类型
  • Nullable 可空类型
  • Literal 预定义类型
截屏2021-07-11 下午12.06.07.png

自动类型判断

  • TS拥有自动的类型判断机制
  • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
  • 所以如果变量的声明和赋值是同时进行的,可以省略掉类型声明
// 声明完变量直接进行赋值
// let c: boolean = false;

// 如果变量的声明和赋值是同时进行的,TS可以自动对变量进行类型检测
// c只能是布尔类型的值
let c = false;
c = true;

类型声明

TS中的类型判断一般用于函数的参数和函数的返回值的情况较多,因为JS中的函数是不考虑参数的类型和个数的

// JS中的函数是不考虑参数的类型和个数的
// function sum(a, b){
//     return a + b;
// }

// console.log(sum(123, 456)); // 579
// console.log(sum(123, "456")); // "123456"

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

let result = sum(123, 456);

类型断言(类型适配)

类型断言,可以用来告诉编辑器变量的实际类型,使用类型断言一定要对当前对象的类型有百分之百的信心,否则会出现严重的错误

/*
* 语法:
*   变量 as 类型
*   <类型>变量
* */
s = e as string;
s = e;

let message: any
message = "abc"
message.endsWith("c") //调用endWith方法的时候,编辑器并不会出现提示,因为此时message还是any类型,即使已经用一个string 类型赋值了 这个时候可以使用类型断言

// 法一
let ddd = (message).endsWith("c")
// 法二
let ddd2 = (message as string).endsWith("c")

元组类型(tuple) 固定长度的数组

// 该数组 第一个元素是number类型 第二个元素是string类型 并且数组长度只能是2位
let arr: [number, string] = [123, "this is ts"]
// arr.push(3) 这边一定要注意元组是固定类型的,是不能够push的,但是这句话编译会通过 平时一定要注意

在声明元组的时候一定要指定类型,如果没有指定类型,其实本质上是一个联合类型数组

let p2 = [1, 'haha'] // p2是一个数组 既不固定长度,也不固定数组
p2[0] = "ddd" // 可以让第一位为字符串,也可以让第二位为数字
p2[1] = 1
p2[2] = 5 // 也可以添加第3位

枚举类型

适合结果在多个值之间进行选择

enum Gender{
    Male,
    Female
}

let i: {name: string, gender: Gender};
i = {
    name: '孙悟空',
    gender: Gender.Male // 'male'
}

联合类型(限制变量在某几个值之间)

let union: string | number
union = 2
union = "haha"

let union2: number | string | boolean | string[]

function merge(n1: number | string, n2: number | string) {
  // 进行简单的类型适配
  if (typeof n1 === "string" || typeof n2 === "string") {
    return n1.toString() + n2.toString() // 这边有点疑问
  } else {
    return n1 + n2
  }
}

let mergeNumber = merge(2, 5)
let mergeString = merge("hello", 1)
console.log(mergeString)

// 明确数据的联合类型 union3 只能是0 1 2 也是字面量类型
let union3: 0 | 1 | 2

字面量类型

// 也可以直接使用字面量进行类型声明
// a只能被赋值为10 不能被赋值为其他值 类似常量 很少使用
let a: 10;
a = 10;

// 字面量形式一般用于或的形式较多
// 可以使用 | 来连接多个类型(联合类型)
let b: "male" | "female";
b = "male";
b = "female";

any 类型

// any 表示的是任意类型,一个变量设置类型为any后相当于对该变量关闭了TS的类型检测
// 使用TS时,不建议使用any类型
// let d: any; 显示any

// 声明变量如果不指定类型,则TS解析器会自动判断变量的类型为any (隐式的any)
let d;
d = 10;
d = 'hello';
d = true;

unknown 类型

// unknown 表示未知类型的值
let e: unknown;
e = 10;
e = "hello";
e = true;

unknown和any的区别在于:any类型的变量可以赋值给任意变量,unknown类型的变量不能直接赋值给其他变量

let s:string;
// d的类型是any,它可以赋值给任意变量
s = d;

e = 'hello';
s = e; // 这句话会报错 即使 e 是字符串 因为 e 原本是 unknown 类型
// unknown 实际上就是一个类型安全的any
// unknown类型的变量,不能直接赋值给其他变量,即使赋值的时候两个变量是同一种类型,赋值之前需要进行类型判断
if(typeof e === "string"){
    s = e;
}

void 类型

// void 用来表示空,以函数为例,就表示没有返回值的函数
function fn(): void{
    console.log('hahah')
}

never 类型

never 表示永远不会返回结果,连空都没有,一般用于处理报错,函数只要报错,立即执行结束

function fn(): never {
  throw new Error("报错了!");
}

object 类型

// object表示一个JS对象 因为JS中一切皆对象,所以单纯这样写,没有任何意义
let a: object;
a = {};
a = function () {
};

一般开发中更多的是对对象的属性进行限制,而不是限制它是不是一个对象

// {} 用来指定对象中可以包含哪些属性,属性的个数要严格相等
// 语法:{属性名:属性值,属性名:属性值}
// 在属性名后边加上?,表示属性是可选的
let b: {name: string, age?: number};
b = {name: '孙悟空', age: 18};

假设要求 c 这个对象有一个name属性,其他属性不做要求,可有可无

// [propName: string]: any 表示任意类型的属性
// propName 是随便起的名字,表示属性名,js中的属性名是字符串类型
let c: {name: string, [propName: string]: any};
c = {name: '猪八戒', age: 18, gender: '男'};

函数结构声明

/*
*   设置函数结构的类型声明:
*       语法:(形参:类型, 形参:类型 ...) => 返回值
* */
// d是一个函数,函数参数是number类型,返回值也是number
let d: (a: number ,b: number) => number;
// d = function (n1: string, n2: string): number{
//     return 10;
// }

数组类型声明

2 种定义方式

  • 类型[]
  • Array<类型>
/*
*   数组的类型声明:
*       类型[]
*       Array<类型>
* */
// string[] 表示字符串数组
let e: string[];
e = ['a', 'b', 'c'];

// number[] 表示数值数值
let f: number[];
// 和上述表达方式一样,都是表示数值的数组
let g: Array;
g = [1, 2, 3];

// 三种声明数组的方式都可以
let list1: number[] = [1, 2, 3, 4]
let list2: Array = [1, 2, 3, 4]
let list3 = [1, 2, 3, 4]

JS 中声明的数组可以是混合类型 在 TS中同样也可以做到

let list1 = [1, "ddd"]
let list2: any[] = [1, "dd", true]

其他

&

// &表示同时 表示 j 对象 必须要有 name 和 age 属性
let j: { name: string } & { age: number };
// j = {name: '孙悟空', age: 18};

类型的别名

// 类型的别名
type myType = 1 | 2 | 3 | 4 | 5;
let k: myType;
let l: myType;
let m: myType;
k = 2;

你可能感兴趣的:(TS基础语法)