你需要知道 TypeScript 的那些事<一>

559 阅读5分钟

你需要知道 TypeScript 的那些事<一>

写在前面:本次 ts 系列文章共4篇,从入门到"入土",且本文仅作为学习笔记。

对于任何语言来说:必定是"用规定的语法,去表达特定语义,最终操作运行时"的一个过程;即语言=文法+语义+运行时

本文内容

  • javascript or TypeScript
  • 类型注解
  • type or interface

本文阅读时间大约为10分钟,请听笔者娓娓道来。

JavaScript or TypeScript

JavaScript

众所周知,JavaScript 是一门弱语言,对类型规范不严格。据我了解,JS 之父当年也没花多长时间就开发出了这门语言。

举个🌰

var a = 123;

a = [1,2,3]
a = '123'

这样做就显得 a 很通用,却加大了项目中的不可预测性。

TypeScript

TypeScript 作为 JavaScript 语言的超集,它为 JavaScript 添加了可选择的类型标注,大大增强了代码的可读性和可维护性。同时,它提供最新和不断发展的 JavaScript 特性,能让我们建立更健壮的组件。

TypeScript 主要有 3 大特点:

  • 始于JavaScript,归于JavaScript

TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并且可以运行在任何浏览器上、Node.js 环境中和任何支持 ECMAScript 的 JavaScript 引擎中。

  • 强大的工具构建大型应用程序

类型允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。

类型是可选的,类型推断让一些类型的注释使你的代码的静态验证有很大的不同。类型让你定义软件组件之间的接口和洞察现有 JavaScript 库的行为。

  • 先进的 JavaScript

TypeScript 提供最新的和不断发展的 JavaScript 特性。

image.png

类型注解

静态类型注解

一旦定义了,就不可以再改变。

举个🌰

// 数字类型的count的变量,这里的: number就是定义了一个静态类型。这样定义后count这个变量在程序中就永远都是数字类型了,不可以改变了
const count: number = 1;
count = "changeNumber"; // 报错

// 函数参数的类型注解,严格的判断接收参数的类型
function greeter (person: string) {
  return 'Hello, ' + person
}

let user = 'Yee'

// 如果传入的不是字符串 那么会直接报错
console.log(greeter(user))

// 函数参数为对象(解构)时
// 一个以上参数
function add({ one, two }: { one: number, two: number }): number {
  return one + two;
}

静态类型检查器

在编写代码的时候会提示类型、语法等是否错误。

举个🌰

// 类型
console.log(4 / []);

// The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

// 语法
let a = (4

// ')' expected.

元组

元组和数组类似,但是类型注解时会不一样,把数组中的每个元素类型的位置给固定住了,这就叫做元组。

// 统一的类型注解 让我们不能很好的限制数组中的每一个值
const man: (string | number)[] = ["法外狂徒张三", 28, "gunner"];

// 元组 明确数组中每一个值得类型
const man: [string, string, number] = ["疾风剑豪李四", "swordman", 28];

联合类型

所谓联合类型,可以认为一个变量可能有两种或两种以上的类型。关键符号是|

举个🌰

// 例如给 狗 取名,你可以叫它 大黄 也可以叫它 123
let dogName : string | number = '大黄'/123

// Return type is inferred as string | number
function changeDogName(name: string | number) {
  dogName = name
  return dogName;
}

type or interface

  • type 是类型别名
  • interface 是接口

type 类型别名用法

举个🌰

// 定义了一个 Man 的类型别名
type Man = { name: string, age: Number };

const man: Man[] = [
  { name: "法外狂徒张三", age: 28 },
  { name: "疾风剑豪李四", age: 28 },
];

interface 接口用法

举个🌰

interface Man {
  name: string;
  age: number;
  weapon ?: string; // 武器是可选
}

const getName = (man: Man) => {
  console.log(man.name + "年龄是:" + man.age);
};

const man = {
  name: "法外狂徒",
  age: 28,
  weapon: "枪",
};

getName(man);

区别

类型别名可以像接口一样工作,但是,有一些细微的区别。 - ts 官方

interface X {
    a: number
    b: string
}

type X = {
    a: number
    b: string
};
  • 扩展方式不同,接口可以继承而类型别名不行
    interface Animal{ name : string };
    interface Bear extends Animal{ honey : boolean };
    
    type Animal = { name = string };
    type Bear = Animal & { honey : boolean };
    
  • 接口可以自动合并,而类型别名不行
    // 同名接口合并
    interface Window{ title : string };
    interface Window{ name : string };
    
    // type 重复定义报错
    type Window{ title : string };
    type Window{ name : string };
    
  • 类型别名可以直接定义类型,而接口必须是对象。
    // type 运算的本质就是类型别名,将 number 这个基本类型别名为 Second ,
    // 但是实际 Second 还是 number 类型,理解了这个你就明白为什么 interface 不具有直
    // 接定义基本数据类型的能力了,因为接口从本质上讲就跟类型没有关系
    type Second = number;
    let time: Second = 10
    
    // 接口不必选值、允许加入任何值和接口里的方法
    interface Girl {
      name: string;
      age: number;
      bust: number;
      waistline?: number; // 加入一个 ? 号代表可选值
      [propname: string]: any; // 属性的名字是字符串类型,属性的值可以是任何类型
      say(): string; // 返回值是 string 类型
    }
    
    // 例如
    const girl = {
      name: "123",
      age: 18,
      bust: 94,
      waistline: 21,
      say() {
        return "123";
      },
    };
    

总结

本文主要讲述了 js 和 ts 的一些区别、常用的 ts 语法以及 type 与 interface 的异同。最近笔者加入了 mini-vue 作者创建的 ts 学习小组,共同学习。有兴趣的话,拉你入群。之后还会有多种形式的对赌学习哦!