TS学习笔记1

本文详细介绍了TypeScript的基础知识,包括安装、基本类型、数组、符号、元组、接口、类、访问限定符、函数重载、泛型等。强调了类型安全和代码规范的重要性,特别讨论了泛型的使用场景和约束。通过实例展示了如何利用TypeScript提高代码质量,并提供了TS在实际项目中的应用示例。
摘要由CSDN通过智能技术生成

重新巩固下typescript基础知识,顺便做做笔记

typescript安装
npm install -g typescript
ts基础类型

注意:均为小写

boolean、number、string、voidundefinednull、symbol
const a: string = 'a'
const a: number = 1
const a: boolean = false

// array两种
const a: number[] = [1, 2, 3]
const a: Array<number> = [1, 2, 3]

// symbol
const a: symbol = Symbol('key')
const b: symbol = Symbol('key')
a === b // false,symbol具有唯一性

// 当一个函数没有返回值,即void,只有undefined和null才可以赋给它
const a: void = undefined

// 类型断言两种方式
const len: number = (<string>value).length
const len: number = (value as string).length
ts其他类型
  • any:任何类型,非必要不建议用,防止写成anyscript,失去typescript意义
  • unknown: 3.0+引入,对照于any,unknown是类型安全的。 任何值都可以赋给unknown,但是当没有类型断言或基于控制流的类型细化时unknown不可以赋值给其它类型,除了它自己和any外。
let value: any;
value; // OK
let value2: unknown;
value2; // ERROR
  • never:表示永不存在的值的类型,是任何类型的子类型,也可以赋值给任何类型
// 永远不会有返回值
function error(message: string): never {
    throw new Error(message);
}
  • 元祖:表示一个已知元素数量和类型的数组,各元素的类型不必相同。
接口
interface User {
	name: string;
	age: number;
	desc?: string; // 可选属性
	readonly gender: string; // 只读属性
	friend: (person: string) => string // 函数类型
}
  • 属性检查

对象字面量存在任何“目标类型”不包含的属性时,会报错

interface Size {
	width: number;
}
function SizeFunc (size: Size) {
	return size.width
}
// error: 'height' not expected in type 'Size'
const result = SizeFunc({width: 5, height: 6})

如上,有三种解决方式:

// 1、类型断言
const result = SizeFunc({width: 5, height: 6} as Size)

// 2、添加字符串索引签名(除了定义的width,其他属性均可传入)
interface Size {
	width: number;
	[propName: string]: any;
}

// 字面量赋给一个新的any变量,不建议这么做
const newResult: any = {width: 5, height: 6}
const result = SizeFunc(newResult)
  • 可索引类型

当对象的key和value有共通性,则可以用可索引

// 学生A信息
studentA = {
	name: 'A',
	age: '12'
}
// 学生B信息
studentB = {
	name: 'B',
	age: '15',
	gender: 'male'
}
// 则可以定义interface为
interface Student {
	[key: string]: string;
}
  • 继承接口

类似不同对象变量有共同的一部分属性,可以提出来写成一个继承接口

interface AddInfo {
	id: string;
	name: string;
	status: number;
	type: number;
}
interface DetailInfo {
	id: string;
	name: string;
	status: number;
	type: number;
	created: number;
	updated: number;
}
// 上述可写为
interface AddInfo {
	id: string;
	name: string;
	status: number;
	type: number;
}
interface DetailInfo extends AddInfo {
	created: number;
	updated: number;
}
// 也可继承多个
……
interface DetailInfo extends AddInfo, UpdateInfo {
……
  • 抽象类
  • 作为其他派生类基类使用,不会被实例化。
  • abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。
  • 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 抽象类中的抽象方法只是声明,不包含具体的功能。
  • 派生类必须定义抽象类中的抽象方法的具体实现(除非该派生类也是抽象类)。
  • 派生类中定义的非抽象类的方法,实例后无法调用。
// 官网例子
abstract class Department {

    constructor(public name: string) {
    }

    printName(): void {
        console.log('Department name: ' + this.name);
    }

    abstract printMeeting(): void; // 必须在派生类中实现
}

class AccountingDepartment extends Department {

    constructor() {
        super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
    }

    printMeeting(): void {
        console.log('The Accounting Department meets each Monday at 10am.');
    }

    generateReports(): void {
        console.log('Generating accounting reports...');
    }
}

let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在
  • 访问限定符

public: 可被外部访问
private: 只能类内部访问,外部不能访问
protected: 可被类内部或类的子类(派生类)访问

  • class可作为接口,且实例化后,可作为变量初始值使用
函数
  • 重载

为函数参数定义类型,提前为所传参数不存在的功能报错

// 不加ts接口定义
function Func(a: number, b?: number, c?: number) {
	if (a) {
		a = b = c
	} else if (a && c) {
		a = c
		b = 2
	}
	return {
		a: a,
		b: b,
		c: c
	}
}
Func(1) // 不报错
Func(1, 2) // 不报错

加入ts接口定义后

在这里插入图片描述

泛型

不确定调用时传入的类型,依靠调用时传入的类型作为传出的参数类型及返回值类型

function Func<T>(arg: T): T {
	return arg
}
const myFunc: <T>(arg: T) => T = Func

多个类型参数

function Func2<T, U>(arg2: [T, U]): [T, U] {
	return [arg2[0], arg2[1]]
}

泛型变量,例如需要获取length属性一类

function FuncArr<T>(arr: Array<T>) {
	return arr.length
}

泛型约束
可以使用继承来约束<T extends xx>

type Params = string | boolean
class Name<T extends Params> {
	……
}
const newP = new Name<number>() // 报错

泛型约束与索引类型

// obj 是对象类型,key 无法在 obj 取到任何值
function getProps(obj: object, key: string) {
	return obj[key] // error
}
// 仅对 obj 做了泛型约束,key 无法确定是否在 obj 上,也会报错
function getProps<T extends object>(obj: T, key: string) {
	return obj[key] // error
}
// 对 key 也进行约束,把它约束为只存在于 obj 属性的类型
function getProps<T extends object, U extends keyof T>(obj: T, key: U) {
  return obj[key] // ok
}

多重类型进行泛型约束的写法

interface A
interface B
// 第一种
interface C extends A, B
class Func<T extends C> {}

// 第二种
class Func<T extends A & B> {}

泛型与 new

 // 声明泛型T是构造函数需要借助new,否则会报错
function factory<T>(type: {new(): T}): T {
  return new type() // ok
}

参考:

  1. TS官网
  2. 掘金-深入浅出TypeScript:从基础知识到类型编程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你关于 TypeScript 中 Symbol 和模块的问题。 首先,Symbol 是 TypeScript 中的一种新的基本数据类型,它可以用来创建唯一的标识符。在 TypeScript 中,Symbol 主要有两种用法: 1. 作为对象属性的键值,用来表示一个对象属性的唯一标识符。 2. 作为一个类的静态属性或方法,用来表示该类的唯一标识符。 下面是一个使用 Symbol 作为对象属性键值的示例: ```typescript const key = Symbol('myKey'); const obj = { [key]: 'value' }; console.log(obj[key]); // 输出'value' ``` 在上面的代码中,我们使用 Symbol('myKey') 创建了一个新的 Symbol,然后将该 Symbol 作为对象 obj 的属性键值,并赋值为'value'。最后,我们通过 obj[key] 的方式来访问该属性,并输出了'value'。 另外,模块是 TypeScript 中的另一个重要概念,它用来组织和管理代码。在 TypeScript 中,模块可以使用 import 和 export 命令来进行导入和导出。下面是一个使用模块的示例: ```typescript // moduleA.ts export const num = 123; // moduleB.ts import { num } from './moduleA'; console.log(num); // 输出123 ``` 在上面的代码中,我们定义了一个名为 num 的常量,并将其导出。然后,在另一个模块中,我们使用 import 命令将 num 导入,并通过 console.log 输出了它的值。 这就是关于 TypeScript 中 Symbol 和模块的简单介绍,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值