Skip to content

JavaScript 的困扰

  1. 不清不楚的数据类型
javascript
let welcome = 'hello world';
welcome();  // TypeError: welcome is not a function
  1. 有 Bug 的逻辑
javascript
const str = Date.now() % 2 ? '奇数' : '偶数';
if (str !== '奇数') {
    alert('Hello');
} else if (str === '偶数') {
    alert('World');
}
  1. 访问不存在的属性
javascript
const obj = {width: 10, height: 15};
const area = obj.width * obj.heigth;
  1. 低级的拼写错误
javascript
const message = 'hello world';
message.toUperCase();

编译 TS

命令行编译

浏览器只认识 JS,所以需要一个工具将 TS 编译为 JS。

  1. 安装
shell
npm i -g typescript
  1. 编译
shell
tsc index.ts

这里的 index.ts 文件放在跟目录中,运行命令后,就会在同级目录中生成 index.js 文件。 命令行编译的弊端是每次修改文件都需要重新编译,一般很少用。

自动化编译

  1. 创建 TS 配置文件(运行下方命令后会在根目录中生成 tsconfig.json 文件)。
shell
tsc --init
  1. 监视目录中的 .ts 文件(运行下方命令会监视目录中所有 .ts 文件并自动编译成 .js 文件,若想监视某个 ts 文件,则在 --watch 后加上文件名)。
shell
tsc --watch
  1. 当编译出错是不生成 .js 文件:在 tsconfig.json 文件中添加 "noEmitOnError": true 即可。

类型声明

定义变量类型

ts
let num: number = 123;
let str: string = 'hello world';
let bool: boolean = true;

定义方法型参类型

ts
function sum(num1: number, num2: number) {
    return num1 + num2;
}
let res = sum(1, 2);
console.log('res', res);

定义方法返回值类型

ts
function sum(num1: number, num2: number): number {
    return num1 + num2;
}
let res: number = sum(1, 2);
console.log('res', res);

字面量

ts
let str: 'Hello'
str = 'Hello'
str = 'World'   // 报错

类型总揽

JS 中的数据类型

  1. string
  2. number
  3. boolean
  4. null
  5. undefined
  6. bigint
  7. symbol
  8. object:Array、Function、Date、Error 等……

TS 中的数据类型

TS 中包含 JS 的所有类型,除此之外新增了六个新类型:

  1. any
  2. unknown
  3. never
  4. void
  5. tuple
  6. enum

新增两个定义类型的方式:

  1. type
  2. interface

注意点

JS 中的内置构造函数(StringNumberBoolean)它们用于创建对应的包装对象,在日常开发时很少使用,在 TS 中也是同理,所以在 TS 中进行类型声明时通常用小写字母(stringnumberboolean

ts
let s1: string = 'Hello';
let s2: String = new String('World');

console.log('typeof s1', typeof s1);    // string
console.log('typeof s2', typeof s2);    // object

常用类型

any

  1. any 表示任意类型,使用 any 类型的变量可以给它赋任意值。
ts
let a: any;
a = 123;
a = 'hello';
a = true;
  1. any 类型的变量可以赋给任意类型的变量,故不建议大量使用 any 类型。
ts
let a: any = 123;
let b: string;
b = a;
console.log('b', b);    // 123

unknown

  1. unknown 类型表示未知类型,它是一个类型安全的 any
ts
let a: unknown;
a = 123;
a = 'hello';
a = true;
  1. unknown 类型的变量默认只能赋给 any 类型的变量,或者 unknown 类型的变量本身。
ts
let a: unknown;
let b: string;
let c: any;

b = a;  // 报错
c = a;  // 正常
  1. 如果想把 unknown 类型的变量赋给其他类型的变量,需要使用类型断言或断言。
ts
let a: unknown;
let b: string;

// 通过判断赋值
if (typeof a === 'string') b = a;

// 断言赋值-as写法
b = a as string;

// 断言赋值-<>写法
b = <string>a;
  1. 读取 any 类型数据的任何属性都不会报错,而 unknown 恰恰相反。
ts
let a: any = 'hello';
console.log(a.length);  // 无警告

let b: unknown = 'hello';
console.log(b.length);  // 警告
console.log((b as string).length);  // 无警告

never

  1. 不要用 never 来定义一个变量,没有任何意义。
  2. never 一般是由 TS 推断出来的。
  3. never 也可以用于限制函数的返回值。
ts
function demo(): never {
    throw new Error('demo');
}

void

  1. void 通常用于函数的返回值类型限制,void 表示函数返回值为空。
  2. 当一个函数没有写 return 语句时,表示函数没有 显式返回值,但是会有一个 隐式返回值:undefined
ts
function demo01(): void {
    console.log('@');
}

function demo02(): void {
    console.log('@');
    return;
}

function demo03(): void {
    console.log('@');
    return undefined;
}
  1. 调用者不应该依赖其返回值进行任何操作。
ts
function demo01(): void {
    console.log('@');
}

function demo02(): undefined {
    console.log('@');
}

let r1 = demo01();
let r2 = demo02();

if (r1) console.log('r1', r1);  // 警告,不要指望 demo01 返回任何东西
if (r2) console.log('r2', r2);  // 正常

object

  1. objectObject 在开发过程中几乎不用,应为两者的范围特别广泛。
  2. object 类型数据可以存储非原始类型数据。
ts
let a: object;

a = {};
a = {name: 'iGma'};
a = [1, 2, 3];
a = () => {};
a = new String('123');
class User {};
a = new User();

// ---------

a = 1;          // 警告
a = 'Hello';    // 警告
a = false;      // 警告
a = null;       // 警告
a = undefined;  // 警告
  1. Object 类型数据可以存储非 nullundefined 类型数据。
ts
let a: Object;

a = {};
a = {name: 'iGma'};
a = [1, 2, 3];
a = () => {};
a = new String('123');
class User {};
a = new User();
a = 1;
a = 'Hello';
a = false;

// ---------

a = null;       // 警告
a = undefined;  // 警告
  1. 声明对象类型:实际开发中声明对象类型数据通常用一下几种方式
ts
// 严格声明每个属性,在赋值时要求每个属性都要赋值,多个数据之间可以用 , ; enter 分割。
let user1: {name: string, age: number};
user1 = {name: 'iGma', age: 20};

// 可选属性,如果某个属性可选,则用 ? 表示。
let user2: {name: string, age?: number};
user2 = {name: 'iGma'};

// 用 enter 取代 , 写法
let user3: {
    name: string
    age?: number
}
user3 = {name: 'iGma', age: 20};
  1. 声明函数类型
  2. 声明数组类型

基于 MIT 许可发布