JavaScript:TypeScript网上笔记总结

本文详细介绍了TypeScript的基础类型(如数值、字符串、布尔、数组、元组、任意类型等),接口的使用、类的定义、函数的重载和泛型,以及命名空间的管理。展示了TypeScript在类型安全编程中的关键概念和用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


TypeScript:

1:基础类型

声明格式:

let 变量名:变量类型 = 赋值内容

数值型 number

let num:number = 123

//支持十进制和十六进制字面量
let hexLiteral: number = 0xf00d; 
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;

字符串类型 string

let str:string = '字符串'

布尔类型 boolean

let bool: boolean = false

数组类型 Array

//数组有两种声明方式
let arr: number[] = [1,2,3]
let arr2:Array<number> = [1,2,3] //这里规范了number类型,那么数组内容就必须是number类型

//数组内容有多种类型
let arr3:(number | string)[] = [1,'nihao']
let arr4:Array<number | boolean> = [true,1] //在声明的时候使用联合类型

元组 Tuple

TS的新概念:元组是固定数量的不同类型的元素的组合

元组变异的数组,其中的元素类型可以是不同的,而且数量固定,好处在于可以把多个元素作为一个单元传递。

let tuple:[number,string] 
tuple =['nihao',1] //Error
tuple =[1,'nihao'] //需要与声明时规范的类型一一对应

//越界时,新增的内容需要是规范的类型中的某一个
tuple.push(true) //error 报错
tuple.push("sss") // 可以

//注意 若声明时添加了readonly->只读元组
let tuple2:readonly [number,string] = [111,'aaa']

任意类型 any

let aaa:any
aaa=1
aaa="123"
aaa=false

void:与any类型相反,表示没有类型

一般用于没有返回值的函数,使用void声明的变量没有用处,void类型的变量只能赋值null 、undefined

function fn():void{
 console.log("This is my warning message");
}
let vv:void = null
let vvv:void= undefined

null 、undefined类型

null 、undefined是所有类型的子类型,表示可以给一个使用number类型的变量赋值null 、undefined

let u: undefined = undefined;
let n: null = null;

never类型

表示用不可能的值,never是任意类型的子类型,但任意类型都不能是never的子类型,任意类型的值都不能赋给never类型的变量除了never类型本身。

//抛出一个值
const errorFunc = (message: string): never => {
  throw new Error(message);
}

//死循环
const infinteFunc = (): never => {
  while (true) { }
}

枚举类型

枚举类型的声明方式和上述的类型有区别:

//enum 变量名{
// 枚举值,枚举值
//}

enum Type {
 red,blue,green
}
Type.red // 0
Type.blue // 1
Type.green // 2

// 枚举值会自增
enum Type2 {
 red,blue=6,green // 0 6 7
}

//枚举值也可以是字符串,
enum Types{
  Red = 'red',
  Green = 'green',
  BLue = 'blue'
}

//异构枚举值:表示枚举值既有字符串又有数字
enum Types{
  No = "No",
  Yes = 1,
}

//接口枚举
enum Types {
  yyds,
  dddd
 }

 interface A {
  red:Types.yyds
 }

let arr:A ={red:Types.yyds}
let arr2:A ={red:"12222"} //报错

//const 声明的枚举会被编译成常量
const enum ttt{
 aa,aaa,bb
}

//反向映射

enum T {
 fail
} 

let n = T.fail //0 
let nn = T[n] // 'fail'

类型断言

语法:

<类型>变量 || (变量名 as 类型)

//js的一个函数获取传来的内容的length
const getLength = target => {
  if (target.length || target.length == 0) {
    return target.length
  } else {
    return target.toString().length
  }
}
//ts 
//这样写是会报错的类型“string | number”上不存在属性“length”。
//类型“number”上不存在属性“length”
const tsGetLength= (target:(string | number)) =>{
  if (target.length || target.length == 0) {
    return target.length
  } else {
    return target.toString().length
  }
}

//类型断言:
//<类型>变量 || (变量名 as 类型)
const tsGetLengthaa= (target:(string | number)) =>{
  if ((<string>target).length || (target as string).length == 0) {
     return (target as string).length
   } else {
     return target.toString().length
   }
 }

类型推论|类型别名

//类型推论
let aa = "你好" //这样定义的变量aa,ts会推论出aa为string类型
aa=123 //error 这样就会报错 不能吧number赋值给string类型

let bb //这时给bb赋值的是null类型
bb = [] //合法
bb = {} //合法
bb = 'hahha' //合法
//类型别名
//let str:string = "你好"
type s = string //定义一个string类型的类型别名
let str:s = "你好"


type T = string | number
let num:T=123
let str1:T="你好"

2:接口

在TS中定义对象的方式要用关键字interface,

接口用来定义一种约束,让数据的结构满足约束的格式。

语法:

interface 接口名 {}
const getFullNameTS = ({fristName,lastName}:{fristName:string,lastName:string}) :string=>{
   return `${fristName}  ${lastName}`
}

//简化
interface nameRule{
 fristName:string,
 lastName:string
}
const getFullNameTS = ({fristName,lastName}:nameRule):string=>{
 fristName:string,lastName:string}) :string=>{
}
//使用接口定义对象
interface Rule{
 name:string,
 age:number
}

let P:Rule={
 name:"ddd",
 age:123
}

//如果此时省略不传,是会报错的
//可选属性 可算操作符 ?
interface Rule{
 name:string,
 age?:number
}

let P:Rule={
 name:"ddd",
}
//只读属性
interface Rule{
 readonly name:string, //此时name为只读属性
 age?:number
}
let P:Rule={
 name:"ddd",
}
P.name = "aaa" //报错
//任意属性
interface Rule{
 readonly name:string, //此时name为只读属性
 age?:number
 [propName:string]:any //索引签名
}//这样声明后定义对象时传递这里没有约束的规则也不会报错

let P:Rule={
 name:"ddd",
 sex:"man"
}
//继承接口
interface Rule{
 readonly name:string, //此时name为只读属性
 age?:number
 [propName:string]:any//索引签名
}//这样声明后定义对象时传递这里没有约束的规则也不会报错

interface Rule2 extends Rule{ // extends 继承的接口名,继承的接口名
 fn():void
}//这样声明后定义对象时传递这里没有约束的规则也不会报错

3:类(不咋用)

//simple class
class Animal{
  name:string //在TypeScript是不允许直接在constructor 定义变量的 需要在constructor上面先声明
  constructor(name:string) {
    this.name = name
    console.log("a "+this.name);
  },
  move(distanceInMeters: number = 0) {
    console.log(`Animal moved ${distanceInMeters}m.`);
  }
}

//类的继承
class Dog extends Animal{
  bark() {
    console.log('Woof! Woof!');
  }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

//公共,私有与受保护的修饰符 public private protected
//上述name字段时class中的变量,修饰符省略时默认为 public
//public表示类的内部外部都可以访问
//private 修饰符 代表定义的变量私有的只能在内部访问 不能在外部访问 (继承的子类 不能访问)
//protected 修饰符 代表定义的变量私有的只能在内部和继承的子类中访问 不能在外部访问

static 静态属性 和 静态方法

//static 定义的属性和方法 不可以通过this 去访问 只能通过类名去调用
class A {
  name:string
  constructor(name:string) {
    this.name = name
  }
  static aa:string = "常量"
 	static run():void{
   this.stop()
   //如果两个函数都是static 静态的是可以通过this互相调用
  }
 	static stop():void{
   //如果两个函数都是static 静态的是可以通过this互相调用
  }
}
A.aa //diaoyong
A.run()

在类中使用接口

// 使用implements关键字
interface C {
  name:string
}

class A implements C{
  name:string
  constructor({name}:C) {
    this.name = name
  }

  static aa :string = "常量"
  staticrun ():string
}

抽象类

//抽象类 需要使用abstract
interface C {
  name:string
}
abstract class A implements C{
  name:string
  constructor(name:string) {
    this.name = name
  }

  static aa :string = "常量"
  abstract run ():string //这里不能写具体分方法,定义的抽象方法必须在派生类实现
}

//派生类

interface C {
  name:string
}

// 继承抽象类,

class B extends A implements C{
  constructor({name}:C){
    super(name)
  }
  run(): string {
    return this.name
  }
}
let b = new B({name:"不好"})
B.aa
console.log('BBBB',b.run(),B.aa);

4:函数

//simple example
const fn = (name:string,age:number):void=>{
	 console.log(`age:${age},name:${name}`);
}

fn('你好',100)//需要与形参上定义的一一对应

//默认值
const fn = (name:string = '哈哈'):string=>{
 return name
}

fn("hhahah") //hhahah
fn() // 哈哈

接口定义函数

interface rule {
 name:string,
 age?:number,
 [propName:string]:any
}

const fn = ({name,age}:rule):void=>{
  console.log(`age:${age},name:${name}`);
}

fn({name:"aa",age:23})

函数重载

重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。
如果参数类型不同,则参数类型应设置为 any。
参数数量不同你可以将不同的参数设置为可选。
function fn(params: number): void 

function fn(params: string, params2: number): void

function fn(params: any, params2?: any): void {
  console.log(params)
  console.log(params2)
}

fn(123)
fn('123',456)

5:联合类型 交叉类型

let phone:number = 183555225222 
//此时需要支持座机号,座机号码一般都是010-2293923
//使用联合类型 |
let phone:number | string = '010-0101010' || 183555225222 

//交叉类型 &
interface Person {
 name:string,
 age:number
}

interface Man {
 sex:string
}

const sss = (man:(Man & Person)):void=>{
 console.log(man.age)
 console.log(man.sex)
 console.log(man.name)
}

sss({
 name:"xiaosong",
 age:12,
 sex:"man"
})

6:泛型

定义函数、类的时候不预先指定类型,在使用的时候再指定类型

//假设存在一个这样的函数 输出a,b参数组成的数组,
function num(a:number,b:number):Array<number>{ 输入number类型的数据返回一个number类型的数组
  return [a,b]
}

console.log(num(1,2));
num('1','2')//这样TS就会报错

//使用泛型
//定义时类型时不明确的
function change<T>(params1:T,params2:T):Array<T>{
 return [params1,params2]
}

//使用时需要明确类型
change<number>(1,2)
change<string>('1','2') // change('1','2')编译器会根据传入的参数自动地确认类型

6.1:泛型约束

function prop<T,K extends keyof T>(obj:T,key:K){ //K extends keyof T 约束了T的类型
  return obj[key]
}

7.命名空间

假设存在两个文件 index1.ts 、 index2.ts

// index1.ts 中定义了一个变量a
const a = 123
// index2.ts 中也定义了一个变量a
const a = 456

这时index2.ts声明的变量会报错,这样定义的变量是全局的,const定义的变量具有唯一性。

解决:

方法一

//index2.ts 中使用export关键字,将index2.ts文件中的a定义为局部变量
export const a = 456

方法二,使用命名空间

//index1.ts中:
namespace A {
 export const a = 123
}
//index2.ts中:
namespace B {
 export const a = 3455
}

//使用时:
console.log(A.a)
console.log(B.a)

嵌套命名空间:

namespace a {
  export namespace b {
    export class Vue {
      parameters: string
      constructor(parameters: string) {
        this.parameters = parameters
      }
    }
  }
}

let v = a.b.Vue
new v('1')

抽离命名空间

//index.ts内容
export namespace VVV {
 export a="抽离"
}
//假设使用时的文件是合index.ts平级
import {VVV} form './index.ts'
console.log(VVV) // 打印出来 : {a:"抽离"}

简化命名空间

namespace A {
  export namespace B {
    export vvv = 12345
  }
}

import temp = A.B.vvv
console.log(temp) 
//这样就可以直接打印出vvv的值

合并命名空间

//重名的命名空间会合并
namespace A {
 export const a = 123
}
namespace A {
 export const b = 123
}
//那么 A这个命名空间里就存在a、b两个变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

待煎的前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值