TypeScript学习总结

93 阅读4分钟

TypeScript 是什么?

TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

TypeScript 与 JavaScript 的区别

TypeScriptJavaScript
JavaScript 的超集,用于解决大型项目的代码复杂性脚本语言,用于创建动态网页
编译期间可以提示错误,提前修改问题编译期间没有提示,运行期间才可以发现问题所在
强类型,支持静态类型和动态类型弱类型,没有静态类型选项
被编译为JavaScript,便于浏览器识别可以直接在浏览器使用
支持模块,泛型和接口不支持
正在不断成长已经稳定,有大量的资料可供查阅

关于Tuple 类型介绍

当我们需要在单个变量中存储不同类型的值时,我们就可以使用元祖了。我们来看一个具体的例子:

let tupleType: [string, number]; 
tupleType = ["herny", 1998];

使用时需要注意的点有:需要使用正确的类型依次初始化变量,否则会报错,读取的时候和数组的读取方法是一样的。只不过元祖里面可以存储不同类型的值。

关于Never类型的介绍

Never表示不存在的值,可以使用Never类型来做类型检查,保证代码的健壮性。

类型断言

TypeScript允许你覆盖它的类型判断,并且以你想要的方式分析它。这种机制被称为类型断言。常见的案例有javascript迁移到typescript的时候类型判断,利用类型断言可以消除错误警告。

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';

交叉类型

TypeScript 交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。例如:

interface IPerson {
  id: string;
  age: number;
}

interface IWorker {
  companyId: string;
}

type IStaff = IPerson & IWorker;

const staff: IStaff = {
  id: 'E1006',
  age: 33,
  companyId: 'EFT'
};

console.dir(staff)

整体加载


// bar.ts
import * as foo from './foo';
// 你可以使用 `foo.someVar` 和 `foo.someType` 以及其他任何从 `foo` 导出的变量或者类型

相对模块路径

  • 如果文件 bar.ts 中含有 import * as foo from './foo',那么 foo 文件必须与 bar.ts 文件存在于相同的文件夹下
  • 如果文件 bar.ts 中含有 import * as foo from '../foo',那么 foo 文件所存在的地方必须是 bar.ts 的上一级目录;
  • 如果文件 bar.ts 中含有 import * as foo from '../someFolder/foo',那么 foo 文件所在的文件夹 someFolder 必须与 bar.ts 文件所在文件夹在相同的目录下。

动态查找

  • 当你使用 import * as foo from 'foo',将会按如下顺序查找模块:

    • ./node_modules/foo
    • ../node_modules/foo
    • ../../node_modules/foo
    • 直到系统的根目录
  • 当你使用 import * as foo from 'something/foo',将会按照如下顺序查找内容

    • ./node_modules/something/foo
    • ../node_modules/something/foo
    • ../../node_modules/something/foo
    • 直到系统的根目录

泛型

在计算机科学中,许多算法和数据结构并不会依赖于对象的实际类型。但是,你仍然会想在每个变量里强制提供约束。例如:在一个函数中,它接受一个列表,并且返回这个列表的反向排序,这里的约束是指传入至函数的参数与函数的返回值:


function reverse<T>(items: T[]): T[] {
  const toreturn = [];
  for (let i = items.length - 1; i >= 0; i--) {
    toreturn.push(items[i]);
  }
  return toreturn;
}

const sample = [1, 2, 3];
let reversed = reverse(sample);

console.log(reversed); // 3, 2, 1

// Safety
reversed[0] = '1'; // Error
reversed = ['1', '2']; // Error

reversed[0] = 1; // ok
reversed = [1, 2]; // ok

在上个例子中,函数 reverse 接受一个类型为 T(注意在 reverse<T> 中的类型参数) 的数组(items: T[]),返回值为类型 T 的一个数组(注意:T[]),函数 reverse 的返回值类型与它接受的参数的类型一样。当你传入 const sample = [1, 2, 3] 时,TypeScript 能推断出 reverse 为 number[] 类型,从而能给你类型安全。与此相似,当你传入一个类型为 string[] 类型的数组时,TypeScript 能推断 reverse 为 string[] 类型,如下例子所示:


const strArr = ['1', '2'];
let reversedStrs = reverse(strArr);

reversedStrs = [1, 2]; // Error

联合类型

在 JavaScript 中,你可能希望属性为多种类型之一,如字符串或者数组。这正是 TypeScript 中联合类型能派上用场的地方(它使用 | 作为标记,如 string | number)。关于联合类型,一个常见的用例是一个可以接受字符串数组或单个字符串的函数:

function formatCommandline(command: string[] | string) {
  let line = '';
  if (typeof command === 'string') {
    line = command.trim();
  } else {
    line = command.join(' ').trim();
  }

  // Do stuff with line: string
}