• 作者:老汪软件技巧
  • 发表时间:2024-09-10 04:01
  • 浏览量:

TypeScript (TS)

TypeScript 是 JavaScript 的超集,这意味着 JS 中能实现的各种操作和语法,在 TS 中都可以实现。TS 添加了可选的静态类型检查,使得开发者可以在开发阶段就发现类型错误,从而提高代码质量和可维护性。此外,TypeScript 还包含了对类、接口、命名空间等面向对象编程特性的支持。

TS安装

npm i -g typescript  // 全局安装 TypeScript

如果想要运行 ts 则可以安装 ts-node。

npm i -g ts-node  // 全局安装 ts-node

ts-node 是一个实用工具,允许你在 Node.js 中直接运行 TypeScript 文件。例如ts-node add.ts,将执行 app.ts 文件中的代码,而无需显式地使用 tsc 命令将其编译为 JavaScript。

类型推断

在 ts 中,类型推断(Type Inference)就是当你没有显式地指定一个变量或参数的类型时,TypeScript 编译器会根据上下文信息来推断这些类型的可能值。ts 检查在编译阶段,所以在编写代码时就可以发现错误。

如下所示,let b = 'hello ts'在 ts 中会类型推断为let b: string。

当已经显式指定 a 为 number 类型时,不能再为 a 赋值为其他类型。

ts 类型any 类型代表任何类型,any 可以赋值成任意类型的值,可以赋给其他类型。一般情况下不用 any,因为它会造成变量污染,例如 x被声明为any类型后,它失去了具体的类型信息,编译器无法在编译阶段对它的使用进行有效的类型检查。

let x: any;
x = 1;
x = "hello";
let y: boolean = true;
y = x;

在 ts 文件中可以创建一个 tsconfig.json 文件进行配置,其中noImplicitAny 是一个重要的编译选项,默认值为 false ,它控制着 TypeScript 编译器是否允许隐式的 any 类型。当你设置 "noImplicitAny": false 时,意味着你允许 TypeScript 编译器接受隐式的 any 类型。

"compilerOptions": {
    "noImplicitAny": true // 不允许any
}

如果 noImplicitAny 设置为 true,那么这段代码在编译时会产生一个警告或错误,指出 x 和 y 的类型没有显式指定。编译器会提示你需要为这些变量提供类型注解。

unknown类型与 any 相似,unknown 可以赋值成任意类型的值,但是不可以赋给其他类型。

不能访问类型为 unknown 变量上面的属性

let obj:unknown = {
    a: 1
}
console.log(obj.a); // obj 的类型是未知,不能访问 a 属性

收缩类型

“收缩类型”(narrowing)是指在运行时通过条件语句(如 if 语句)来缩小一个值的类型范围。当你使用 unknown 类型时,经常需要通过类型保护来进行类型收缩,以便安全地使用这些值。

let x: unknown = 1
x + 1  // 报错
// 使用 typeof 进行类型保护
if (typeof x === 'number') {
    // 在这个 if 块内,TypeScript 知道 x 是 number 类型
    x + 1;  // 不再报错
}

never 类型

never 类型表示的是那些永远不会出现的类型,常用来定义永不返回的函数。

function foo(): never {
    throw new Error('error')
}
// 这个函数永远不会返回
function loopForever(): never {
    while (true) {
        // 无限循环
    }
}

js中就有的类型

_深入理解计算机系统pdf_深入理解计算机系统mobi

const a: boolean = true // 布尔类型
const b: string = "hello"
const c: number = 123
const d: symbol = Symbol()
const e: bigint = 123n
const obj: object = {}
const arr: Array = [1, 2, 3]
const foo: Function = () => { }
// 允许any的情况下undefined和null 会被当成any
const un = undefined
const nul: null = null
// 大写的 String 专门用来声明包装类
const str = new String('hello')
const obj2 = new Object()
let o: Object
o = 1
o = '1'
o = undefined // 报错 undefined 没有构造函数

值类型

用一个值作为类型,例如:let x: 1;

// 值类型
let x: 'a' // 'a'类型

联合类型

表示多个类型的值之一。例如:let value: string | number;

// 联合类型
let y: string | number
y = 123
y = '123'
// 联合的值类型
function color(color: '红' | '黄') {
}
color('红')
color('黄')

交叉类型

表示多个类型的组合。例如:type DraggableAndResizable = Draggable & Resizable;

// 交叉类型
let obj3: {foo: string} & {bar: string}
obj3 = {
    foo: 'hello',
    bar: 'world'
}

type

类型别名,可以定义新的类型名称。例如:type Point = { x: number; y: number };

// type声明唯一
type Age = number // Age类型
let age: Age = 18
type World = 'world'
type Greeting = `hello ${World}`
type Common = string | number | boolean

数组使用类型后缀 []

可以使用类型后缀 [] 来定义一个数组类型,其中包含特定类型的元素。

let arr: number[] = [1,2,3]
arr.push('4') // 报错 ts中数组里面要是同一个类型
let strings: string[] = ['a', 'b', 'c'];
let arr:(string | number)[] = [1,2,3,'hello']

使用Array

可以使用 Array 来定义数组类型,其中 T 是数组元素的类型。

let numbers: Array = [1, 2, 3];
let strings: Array = ['a', 'b', 'c'];
let arr: Array = [1,2,3,'hello']

可以设置数组只读不写

const arr1: readonly number[] = [1,2,3] // 只读不可写
let arr2: ReadonlyArray = [1]
let arr3: Readonly = [1]

元组(Tuple)

元组类型允许你定义一个数组,其中元素的数量和类型都是固定的。元组允许数组存储不同类型,元组是ts特殊的数组类型。

// 元组声明写在方括号里面
let point: [number, number] = [10, 20];
let person: [string, number, boolean] = ['Alice', 25, true];
    
// 元组可以设置可选,用 ? 表示
let arr: [number , string?, boolean?] = [1]

函数函数默认是 void 类型,函数 return 的是什么类型就是什么类型。

function foo() { // function foo1(): number
    let a = 1
    return a 
}

上面这段代码返回的是 a ,根据类型推断 a 是 number 类型,所以函数 foo 是 number 类型。

函数重载

函数重载(Overload)是 TypeScript 中的一种特性,允许你为同一个函数名称提供多个不同的函数签名(Signatures),以便根据参数的不同类型执行不同的逻辑。

// 函数重载 -- 当需要根据参数类型的不同执行不同的逻辑
function reverse(str: string): string
function reverse(arr: number[]): number[]
    
function reverse(str: string | number[]): string | number[] {
    if (typeof str === 'string') {
        return str.toString().split('').reverse().join('')
    }else {
        return str.slice().reverse()
    }
}
console.log(reverse('asadftrgy'));
console.log(reverse([1,2,3,4]));

这段代码定义了一个名为 reverse 的函数,该函数可以根据传入参数的类型执行不同的逻辑。具体来说,它有两个重载声明和一个实际的函数实现。