TypeScript学习之旅(持续更新)

97 阅读4分钟

nodejs.cn/typescript/…

面向 JavaScript 程序员的 TypeScript

推理类型

TypeScript 了解 JavaScript 语言,并会在许多情况下为您生成类型。例如,在创建变量并将其分配给特定值时,TypeScript 将使用该值作为其类型。

定义类型

ts可以使用interface描述对象的参数等,

用interface声明后类似 : TypeName 的语法来声明 JavaScript 对象符合新 interface 的形状:

interface User{
  name:string;
  id:number;
}

const user:User={
  name:"Hays",
  id:0,
}

我们可以对类使用接口声明,类似于构造器

interface User{
	name:string;
	id:number;
}

class UserAccount{
	name:string;
	id:number;
	constructor(name:string,id:number){
		this.name = name;
		this.id = id;
	}
}
const user:User = new UserAccount("liming",12);

您可以使用接口来注释参数并将值返回给函数:

interface User {
  name: string;
  id: number;
}
function getAdminUser(): User {
  //...
}

function deleteUser(user: User) {
  // ...
}

组合类型

联合和泛型

联合

使用联合,你可以声明一个类型是多种类型之一

例如您可以将 boolean 类型描述为 true 或 false:

type MyBool = true | false;
type WindowStates = "open" | "closed" | "minimized";
type LockStates = "locked" | "unlocked";
type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9;

联合还可以处理含有不同类型的参数

function getLength(obj: string | string[]) {
  return obj.length;
}

要了解变量的类型,可以使用typeof

泛型

泛型为类型提供变量。一个常见的例子是数组。没有泛型的数组可以包含任何东西。具有泛型的数组可以描述数组包含的值。

type StringArray = Array<string>;
type NumberArray = Array<number>;
type ObjectWithNameArray = Array<{ name: string }>;

您可以声明自己的使用泛型的类型:

interface Backpack<Type> {
  add: (obj: Type) => void;
  get: () => Type;
}

//定义了一个实现接口的类
declare const backpack: Backpack<string>;

const object = backpack.get();

backpack.add(23);

基础知识

tsc,TypeScript 编译器

通过运行 typescript 包为我们安装的命令 tsc 来检查ts文件。

tsc hello.ts

日常类型

string。number,boolean

数组

可以使用number[],或者string[],也可以写成Array

any

当你不希望某个特定的值导致类型检查错误时,可以使用它

当一个值的类型是any时,可以访问他的任何属性,想函数一样调用它

let obj: any = { x: 0 };
// None of the following lines of code will throw compiler errors.
// Using `any` disables all further type checking, and it is assumed 
// you know the environment better than TypeScript.
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;

当你没有指定类型,并且 TypeScript 不能从上下文推断它时,编译器通常会默认为 any。

函数

参数类型注释

// Parameter type annotation
function greet(name: string) {
  //                 ^^^^^^^^
  console.log("Hello, " + name.toUpperCase() + "!!");
}

返回类型注释

function getFavoriteNumber(): number {
  //                        ^^^^^^^^
  return 26;
}

匿名函数


// Contextual typing for function
names.forEach(function (s) {
  console.log(s.toUppercase());
});

// Contextual typing also applies to arrow functions
names.forEach((s) => {
  console.log(s.toUppercase());
});

对象类型

可选属性

function printName(obj:{first:string,last?:string}){
}
printName({first:"Bob"});
printName({first:"Alice",last:"Allision"})

这说明了对象中的last属性是可选

当不确定某个属性是否存在,我们可以这样读取数据

例如

console.log(obj.last?.toUpperCase());

联合类型

定义联合类型

function printId(id: number | string) {
  console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");

使用联合类型

联合类型的使用只有在对联合的所有类型都有效的情况下才允许操作,例如,如果您有联合 string | number,则不能使用仅在 string 上可用的方法

解决办法是缩小联合,确定具体类型

例如

function printId(id: number | string) {
  if (typeof id === "string") {
    // In this branch, id is of type 'string'
    console.log(id.toUpperCase());
  } else {
    // Here, id is of type 'number'
    console.log(id);
  }
}

若是Array类型

function welcomePeople(x: string[] | string) {
  if (Array.isArray(x)) {
    // Here: 'x' is 'string[]'
    console.log("Hello, " + x.join(" and "));
  } else {
    // Here: 'x' is 'string'
    console.log("Welcome lone traveler " + x);
  }
}

当然我们也可以直接使用联合类型中的共同属性

例如

function getFirstThree(x: number[] | string) {
  return x.slice(0, 3);
}

类型别名

我们可以创建类型别名来表示对象类型或者联合类型

type Point = {
  x:number;
  y:number;
}
function printCoord(pt:Point){
}

printCoord({ x: 100, y: 100 });
type ID = number| string

接口

接口和别名的区别

InterfaceType
扩展接口```
interface Animal { name: string } interface Bear extends Animal { honey: boolean } const bear = getBear() bear.name bear.honey
```通过交集扩展类型```
type Animal = { name: string } type Bear = Animal & { honey: boolean } const bear = getBear(); bear.name; bear.honey;
| 向现有接口添加新字段```
interface Window {   title: string }  interface Window {   ts: TypeScriptAPI }  const src = 'const a = "Hello World"'; window.ts.transpileModule(src, {});
``` | 类型创建后无法更改```
type Window = {   title: string }  type Window = {   ts: TypeScriptAPI }   // Error: Duplicate identifier 'Window'.
```          |

## null和undefined

strictNullChecks开启后null和undefined不能正常访问。

解决办法:

1、缩小范围,确定类型

2.非空断言运算符(后缀!)

在任何表达式之后写 ! 实际上是一个类型断言,该值不是 null 或 undefined:

例如

function fx(x?:number|null){ console.log(x!.toFixed()) }


## 枚举

## bigint

bigint可以用于非常大的整数

// Creating a bigint via the BigInt function const oneHundred: bigint = BigInt(100);

// Creating a BigInt via the literal syntax const anotherHundred: bigint = 100n;


## symbol

# 类型缩小