一、ts官网-日常类型 笔记

基础知识

日常类型
  • 基础类型:string,number和boolean
类型名称 String、Number 和 Boolean(以大写字母开头)是合法的,但指的是一些很少出现在代码中的特殊内置类型。
始终使用 stringnumberboolean 作为类型。
  • 数组
请注意,[number] 是另一回事;请参阅 元组 部分
  • any
任何类型的值,或者几乎任何其他东西在any语法上是合法的
  • 变量的类型注释
let myName: string = "Alice";
  • 函数:指定函数的输入和输出值的类型
  • 参数类型注解:在每个参数后面加上类型注解,声明函数接受哪些类型的参数
// Parameter type annotation
function greet(name: string) {
 console.log("Hello, " + name.toUpperCase() + "!!");
}
  • 返回类型注解:添加返回类型注释。返回类型注释出现在参数列表之后
function getFavoriteNumber(): number {
 return 26;
}
  • 返回 Promise 的函数:想注释一个返回 Promise 的函数的返回类型,你应该使用 Promise 类型
async function getFavoriteNumber(): Promise<number> {
   return 26
}
  • 匿名函数
[类型推断]: 来确定 s 将具有的类型
称为上下文类型,因为函数发生的上下文告知它应该具有什么类型。
  • 对象类型:除了基础类型外,最常见的就是对象类型 【 ; 】 来分隔属性
// The parameter's type annotation is an object type
function printCoord(pt: { x: number; y: number }) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 3, y: 7 });
  • 可选属性:指定部分或全部属性是可选的,请在属性名称后添加 ?
function printName(obj: { first: string; last?: string }) {
 // ...
}
// Both OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });

注意:当你从可选属性中读取数据时,你必须在使用它之前检查 undefined。

function printName(obj: { first: string; last?: string }) {
 // Error - might crash if 'obj.last' wasn't provided!
 console.log(obj.last.toUpperCase());
'obj.last' is possibly 'undefined'.
 if (obj.last !== undefined) {
  // OK
  console.log(obj.last.toUpperCase());
 }
 // A safe alternative using modern JavaScript syntax:
 console.log(obj.last?.toUpperCase());
}
  • 联合类型:用各种运算符从现有类型中组合他们
  • 定义联合类型:由两种或多种其他类型组成的类型,表示可能是这些类型中的任何一种的值
function printId(id: number | string) {
 console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// Error
printId({ myID: 22342 });
Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
  • 使用联合类型 :提供与任何联合成员匹配的类型即可
function printId(id: number | string) {
 console.log(id.toUpperCase());
 //Property 'toUpperCase' does not exist on type 'string | number'.
 //Property 'toUpperCase' does not exist on type 'number'.
}

注意:用代码缩小联合
TypeScript 知道只有 string 值才会有 typeof 值 “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.isArray 这样的函数

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);
	 }
 }

类型的联合似乎具有这些类型的属性的交叉,这可能会令人困惑。这不是意外 - union 这个名字来自于类型理论。联合 number | string 是通过取每种类型的值的联合组成的。请注意,给定两个具有关于每个集合的相应事实的集合,只有这些事实的交叉适用于集合本身的并集。例如,如果我们有一个房间里有戴帽子的高个子,而另一个房间里有戴帽子的说西班牙语的人,在组合这些房间后,我们对每个人的唯一了解就是他们必须戴帽子。

  • 类型别名【type Name = {}】:任何类型的名称,希望多次使用同一个类型并用一个名称引用它
type Point = {
  x: number;
  y: number;
};
 
// Exactly the same as the earlier example
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });

类型别名可以为任何类型命名,可以命名联合类型

type ID = number | string;

注意,别名只是别名 - 你不能使用类型别名来创建相同类型的不同/独特的 “版本”。

type UserInputSanitizedString = string;
 
function sanitizeInput(str: string): UserInputSanitizedString {
  return sanitize(str);
}
 
// Create a sanitized input
let userInput = sanitizeInput(getInput());
 
// Can still be re-assigned with a string though
userInput = "new input";

这段代码可能看起来非法,但根据 TypeScript 是可以的,因为这两种类型都是同一类型的别名

  • 接口【interfaces】:是命名对象类型的另一种方式
interface Point {
  x: number;
  y: number;
}
 
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });

ts结构类型类型系统:只关心类型的结构和功能

  • 类型别名和接口的区别
    1.类型别名和接口非常相似,在很多情况下你可以在它们之间自由选择
    2.interface 的几乎所有功能都在 type 中可用
  • 区别:
    1.类型【type】无法重新打开以添加​​新属性,仅可通过【交叉扩展类型】添加
    2.接口【interface】始终可扩展新属性,a.可以【扩展接口extends】添加;b. 向现有接口添加新字段

Interface

扩展接口【extends】

interface Animal {
 name: string;
}
interface Bear extends 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

通过交叉扩展类型 【&】

type Animal = {
 name: string;
}
type Bear = Animal & { 
 honey: boolean;
}
const bear = getBear();
bear.name;
bear.honey;

类型创建后无法更改

type Window = {
 title: string;
}
type Window = {
 ts: TypeScriptAPI;
}
// Error: Duplicate identifier 'Window'.

区别总结:在大多数情况下,可以根据个人喜好进行选择,想要启发式方法,请使用 interface

  1. 在 TypeScript 4.2 版之前,类型别名 可能出现在错误信息中,有时代替等效的匿名类型(可能需要也可能不需要)。
    接口将始终在错误消息中命名。

  2. 类型别名不得参与在声明合并中,但接口可以参与在声明合并中。

  3. 接口只能用于 声明对象的形状,而不是重命名基础类型。

  4. 接口名称将在错误消息中显示为 总是以原来的形式出现,但仅当它们被名称使用时。

  • 类型断言【as】:对于 ts 无法知道的值类型,可以使用类型断言【as】来指定其具体的类型

1.可以使用类型断言【as】来指定更具体的类型

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;

2.还可以使用尖括号语法【<>】(除非代码在 .tsx 文件中),它是等效的:

//You can also use the angle-bracket syntax (except if the code is in a .tsx file), which is equivalent:

const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");

提醒:因为类型断言在编译时被删除,所以没有与类型断言关联的运行时检查。如果类型断言错误,则不会产生异常或 null。

有时,此规则可能过于保守,并且不允许可能有效的更复杂的强制转换。如果发生这种情况,你可以使用两个断言,首先是 any(或 unknown,我们稍后会介绍),然后是所需的类型

const a = expr as any as T;
  • 字面类型:除了通用类型 string 和 number 之外,我们还可以在类型位置引用特定的字符串和数字

就其本身而言,字面类型并不是很有价值,变量只能有一个值并没有多大用处!

let x: "hello" = "hello";
// OK
x = "hello";
// ...
x = "howdy";
//Type '"howdy"' is not assignable to type '"hello"'.

但将【字面量组合成联合】,你可以表达更有用的概念

function printText(s: string, alignment: "left" | "right" | "center") {
  // ...
}
printText("Hello, world", "left");
printText("G'day, mate", "centre");
//Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.

数字字面类型的工作方式相同:

function compare(a: string, b: string): -1 | 0 | 1 {
  return a === b ? 0 : a > b ? 1 : -1;
}

将这些与非字面类型结合使用

interface Options {
  width: number;
}
function configure(x: Options | "auto") {
  // ...
}
configure({ width: 100 });
configure("auto");
configure("automatic");
Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.

  • 字面推断 :当你使用对象初始化变量时,TypeScript 假定该对象的属性可能会在以后更改值。
declare function handleRequest(url: string, method: "GET" | "POST"): void;
 
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
// 错误 Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
  1. as const:将整个对象转换为类型字面
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);
  1. as 通过在任一位置添加类型断言来更改推断
  2. const req = { url: "https://example.com", method: "GET" as "GET" };
  3. handleRequest(req.url, req.method as "GET");

null 和 undefined

表示值不存在或未初始化的值:null 和 undefined。

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

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

function liveDangerously(x?: number | null) {
 // No error
 console.log(x!.toFixed());
}

就像其他类型断言一样,这不会改变代码的运行时行为,所以当你知道值不能是 null 或 undefined 时,只使用 ! 很重要。


枚举 【Enums】

允许描述一个值,该值可能是一组可能的命名常量之一
不是对 JS 的类型级添加,而是添加到语言和运行时的东西


不太常见的基础类型
  • bigint:用于非常大的整数
  • symbol:用于通过函数 Symbol() 创建全局唯一引用
  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值