思考一个问题,JavaScript是一门非常优秀的编程语言,但是直到今天,JavaScript在类型检测上依然是毫无进展,所以我们需要学习TypeScript,这不仅仅可以为我们的代码增加类型约束,而且可以培养我们前端程序员具备类型思维

零基础学习 之 TS-LMLPHP

目录

一、认识TypeScript

二、配置TypeScript的环境

1. 使用ts-node

01 - 安装ts-node及其依赖包

02 - 代码栗子,创建 .ts 文件

03 - 使用 ts-node

2. 使用webpack进行配置

01 - 项目初始化

02 - 安装各种东东

03 - 新增一个index.html模版

04 - package.json配置

05 - webpack.config.js配置

06 - 生成tsconfig.json 

07 - 创建src文件夹,里面再创建main.ts 

08 - npm run serve运行即可

三、变量的声明

01. 声明变量的关键字

02. 类型推导/推断

四、 TypeScript的类型

01. number 类型

02. boolean 类型

03. tring 类型

04. Array 类型 

05. 对象 类型

06. null 类型

07. undefined 类型

08. symbol 类型

09. any 类型 

10. unknown 类型

11. void 类型

12. never 类型 

13. tuple 元组类型

14. 对象 类型

15. 可选 类型

16. 联合 类型

17. 类型别名


一、认识TypeScript

TypeScript: JavaScript With Syntax For Types.

GitHub说法:TypeScript is a superset of JavaScript that compiles to clean 
TypeScript官网:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

翻译一下:TypeScript是拥有类型的JavaScript超集,它可以编译成普通、干净、完整的JavaScript代码。

  • JavaScript所拥有的特性,TypeScript全部都支持
  • 在语言层面上,不仅仅增加了类型约束,而且包括一些语法的扩展
  • TypeScript在实现新特性的同时,总是保持和ES标准的同步甚至是领先
  • TypeScript最终会被编译成JavaScript代码,不需要担心兼容性问题
  • TypeScript不仅让JavaScript更加安全,而且给它带来了诸多好用的好用特性

安装TypeScript

# 安装命令
npm install typescript -g

# 查看版本
tsc --version

二、配置TypeScript的环境

1. 使用ts-node

01 - 安装ts-node及其依赖包

npm install ts-node tslib @types/node -g

02 - 代码栗子,创建 .ts 文件

// 规定message的类型为string
let message: string = 'hello'

// 报错!
// message = 123

// 规定参数类型为string
function abc(name: string){}

console.log(message);

// 因为ts默认作用域会在一个,这样设置导出,会让文件形成单独作用域
export {}

03 - 使用 ts-node

// ts-node可以直接运行TypeScript代码
ts-node 文件名

零基础学习 之 TS-LMLPHP

2. 使用webpack进行配置

具体可看之前的webpack文章,webpack 之 零基础使用常用的Loader  ,这里我快速过一遍哈

01 - 项目初始化

npm init -y

02 - 安装各种东东

npm install webpack webpack-cli webpack-dev-server html-webpack-plugin ts-loader typescript -D

03 - 新增一个index.html模版

零基础学习 之 TS-LMLPHP

04 - package.json配置

零基础学习 之 TS-LMLPHP

05 - webpack.config.js配置

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/main.ts',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'boundle.js'
  },
  devServer: {},
  resolve: {
    extensions: ['.js', '.ts', '.json']
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html'
    })
  ]
};

06 - 生成tsconfig.json 

// 先不用理这个文件,后续讲解
tsc --init

07 - 创建src文件夹,里面再创建main.ts 

const message: string = '123'

console.log(message);

08 - npm run serve运行即可


三、变量的声明

01. 声明变量的关键字

声明了类型后TypeScript就会进行类型检测,声明的类型可以称之为类型注解

数据类型的大小写是有区别的 ,用小写即可

  • string ( 小写 ) 是TypeScript中定义的字符串类型
  • String ( 大写 ) 是ECMAScript中定义的一个类

02. 类型推导/推断

如果不写数据类型,会讲赋值的值的类型,作为标识符的类型

零基础学习 之 TS-LMLPHP

四、 TypeScript的数据类型

零基础学习 之 TS-LMLPHP

01. number 类型

let demo: number = 22;     // 十进制
let demo: number = 0b110;  // 二进制
let demo: number = 0o555;  // 八进制
let demo: number = 0xf23;  // 十六进制

02. boolean 类型

let bool: boolean = true
let bool: boolean = 30 > 20

03. tring 类型

const name: string = 'star'
const info: string = `my name is ${name}`

04. Array 类型 

// 需要制定数组类型,同时制定数组内部值的类型

// 写法一 : 不推荐
const name: Array<string> = []

// 写法二 : 推荐
const name: string[] = []

05. 对象 类型

// 使用自动推导即可
const info = {
  name: 'star',
  age: 18
};

06. null 类型

const n: null = null

07. undefined 类型

const n: undefined = undefined

08. symbol 类型

// Symbol 生成独一无二的key
const info = {
  [Symbol('name')]: 'star',
  [Symbol('name')]: 'coder'
};

09. any 类型 

// 任意类型都可赋值,也可赋值给任何类型
let message: any = 'star';

message = 123;
message = true;

10. unknown 类型

function foo() {
  return 'string';
}
function bar() {
  return 123;
}
let flag: boolean = true;

// result 不知是什么类型时可用
let result: unknown;
if (flag) {
  result = foo();
} else {
  result = bar();
}

和any类型的区别 

  • unknown类型只能赋值给unknown类型和any类型
  • any类型可以赋值给任何类型
let result: unknown;
// 报错
let num: number = result

// 可以赋值
let unres: unknown = result
let anyres: any = result

11. void 类型

// 当函数没有返回值的时候,该函数就是void类型,不写也阔以,会自动推导
const sum = (num1: number, num2: number): void => {
  console.log(num1, num2);
};

12. never 类型 

// 当永远没有返回值的时候,用never

function foo(): never {
  while (true) {}
}
function bar(): never{
  throw new Error()
}

13. tuple 元组类型

// tuple 多种元素的组合

const info: [string, number, number, string] = ['star', 1, 2, 'coder'];

14. 函数的参数及返回值 类型

// 可指定函数的参数类型和个数和返回值的类型   name: string => 指参数类型为string    string => 指函数的返回值类型为string,可不写,会推导
function getInfo(name: string): string {
  return name;
}

// 匿名函数不需要写类型,TypeScript会根据forEach函数的类型以及数组的类型  推断出  item的类型
// 因为函数执行的上下文可以帮助确定参数和返回值的类型
const names = ['a', 'b', 'c'];
names.forEach((item) => {});

15. {} 对象类型

// info是一个对象类型,对象中有两个属性

function find(info: { name: string; age: number }) {}

16. ? 可选类型

// money是可选类型,可传可不传
function find(info: { name: string; age: number; money?: number }) {}

find({ name: 'coder', age: 123 });
find({ name: 'coder', age: 123, money: 1000 });

17. | 联合类型

// 联合类型  可以为其中的一种
function find(id: string | number) {
  // 使用联合类型的值的时候,需要特别小心
  switch (typeof id) {
    case 'string':
      break;

    case 'number':
      break;
  }
}

find(123);
find('456');

可选类型和联合类型的关系

一个参数是一个可选类型的时候,它其实类似于这个参数是 类型|undefined的联合类型

function foo(message?: string) {}
// 这里可以不传
foo();

function foo(message: string | undefined) {}
// 但是这里还是要传一个值
foo(undefined);

18. type 类型别名

// type 用于定义类型别名
type IdType = string | number | boolean;

// 太长了
function idSet(id: string | number | boolean) {}
// 取别名可以优化
function idSet(id: IdType) {}

19. as 类型断言

// 默认是 HTMLElement 类型,范围太广了,有时会出错
// const oDom: HTMLElement = document.getElementById('star');

// <img  id="star" />
// 用 as 指定是什么元素类型
const oDom: HTMLImageElement = document.getElementById('star') as HTMLImageElement;
oDom.src = 'url地址';


// 不推荐乱使用
const message = 'hello'
// 可以跳过类型检测,无敌,不推荐使用
const num: number = (message as any) as number

20. ! 非空类型断言

// 这样是没问题的
function printStrLength(message: string) {
  console.log(message.length);
}
printStrLength('aaa');
printStrLength('11');

// 但是如果参数变成了可选类型呢,编译就会报错
function printStrLengthCan(message?: string) {
  console.log(message.length);
}

// 解决方式一
function printStrLengthOne(message?: string) {
  // 做个if判断即可
  if (message) {
    console.log(message.length);
  }
}

// 解决方式二
function printStrLengthTwo(message?: string) {
  // 加个非空断言 , 保证message一定有值
  console.log(message!.length);
}

21. ?.可选链

可选链事实上并不是TypeScript独有的特性,它是ES11(ES2020)中增加的特性

  • 可选链使用可选链操作符 ?.
  • 它的作用是当对象的属性不存在时,会短路,直接返回undefined,如果存在,那么才会继续执行
// 定义一个类型
type Person = {
  name: string;
  // 可能有,可能没有
  friend?: {
    name: string;
    // 可能有,可能没有
    age?: number;
  };
};

const info: Person = {
  name: 'star'
};
const info2: Person = {
  name: 'star',
  friend: {
    name: 'coder'
  }
};

// 如果有friend,继续往后取,如果没有,返回undefined,相当于短路
console.log(info.friend);
console.log(info.friend?.name);
console.log(info.friend?.age);
// 类似于,可以节省很多代码
if (info.friend) {
  if (info.friend.name) {
    console.log(info.friend.name);
  }
  if (info.friend.age) {
    console.log(info.friend.age);
  }
}

export {};

22. !! 取boolean类型

const message: string = 'hello'
const flag: boolean = Boolean(message)
// !! 可以用作取反
const flag1: boolean = !!message

23. ?? 

// ?? 有值的时候取前面的值,没值的时候取后面的值
// 和三目运算符很像,不过更简洁一点

const message: string | null = null;
const res: string = message ?? 'hello';
console.log(res); // hello

const message1: string | null = 'coder';
const res1: string = message ?? 'hello';
console.log(res1); // coder

24. 字面量类型

字面量类型的类型和值要保持一致

const message = 'hello';  // 这个message的类型就是hello
let mess = 'hello'  //这个mess的类型才是string

let me : 123 = 123
me = 456 // 报错

字面量类型的意义 : 必须结合联合类型

let align: 'left' | 'right' | 'center' = 'left'
// 再次修改值的时候,只能允许修改定义了类型的值
align = 'right'

25. 字面量推理

栗子

const info = {
  url: 'www.baidu.com',
  method: 'GET'
};

function request(url: string, method: 'GET' | 'POST') {
  console.log(url, method);
}

// 这里info.method会报错,因为默认推导method是字符串类型,所以不能这么传
request(info.url,info.method)

解决方式一 : 推荐

// 定义一个类型
type requestType = {
  url: string;
  method: 'GET' | 'POST';
};

// 定义对象的时候就使用这个类型
const info: requestType = {
  url: 'www.baidu.com',
  method: 'GET'
};

function request(url: string, method: 'GET' | 'POST') {
  console.log(url, method);
}

request(info.url, info.method);

解决方式二 : 

const info = {
  url: 'www.baidu.com',
  method: 'GET'
};

function request(url: string, method: 'GET' | 'POST') {
  console.log(url, method);
}

// 使用类型断言
request(info.url, info.method as 'GET');

解决方式三 :

function request(url: string, method: 'GET' | 'POST') {
  console.log(url, method);
}

// 这里使用类型断言成const,其内部的属性值都变成了readeronly
const info = {
  url: 'www.baidu.com',
  method: 'GET'
} as const;

request(info.url, info.method);

export {};

 

 

06-10 15:49