TS对象类型(Object Types)和函数类型

举报
林太白 发表于 2025/03/14 16:41:35 2025/03/14
【摘要】 TS对象类型(Object Types)和函数类型

TS对象类型(Object Types)和函数类型

对象类型(Object Types)

object: 用于表示非原始类型的值(即排除 number、string、boolean、null 和 undefined)

let obj: object = { name: "Alice", age: 25 };
常见的对象是这样子:
let person= {}

当我们约定为对象:
let person: {} = {}
// {} 'person'
console.log(person,'person');
// 添加属性以后
let person: { name: string } = {
    name: '同学'
}
console.log(person,'person');
// 输出的结果就是:
{name: '同学'}'person'

如果这个对象之中有方法呢

指定对象的多个属性类型时,使用 `;`(分号)来分隔
那我们的方法就写成了
let person: { name: string; sayHi(): void } = {
    name: 'jack',
    sayHi() {
        console.log('sayHi');
    }
}
console.log(person,'person');

优化一下我们上面的函数
通过换行来分隔多个属性类型,可以去掉 `;`
let person: {
    name: string
    sayHi(): void
} = {
    name: 'jack',
    sayHi() {console.log('sayHi');}
}

使用类型别名简化对象约束

// 创建类型别名
type Person = {
    name: string
    sayHi(): void
}
// 使用类型别名作为对象的类型
let person: Person= {
    name: 'jack',
    sayHi() {console.log('sayHi');return 'sayHi';}
}
console.log(person,'person');

接下来我们要调取上面对象之中的sayHi 方法,这个时候我们要传入一个参数type

// 创建类型别名
type Person = {
    name: string
    sayHi(type:string,total:string): void
}
// 使用类型别名作为对象的类型
let person: Person= {
    name: 'jack',
    sayHi(type,total) {
        console.log('sayHi');
        console.log(type,'type');
        console.log(total,'total');
        return 'sayHi';
    }
}
console.log(person,'person');

把上面的方法改成我们的箭头函数形式

// 创建类型别名
type Person = {
    name: string
    sayHi:(type:string,total:string)=>void
}
// 使用类型别名作为对象的类型
let person: Person= {
    name: 'jack',
    sayHi(type,total) {
        console.log('sayHi');
        console.log(type,'type');
        console.log(total,'total');
        return 'sayHi';
    }
}
console.log(person,'person');

但如果其实total并不需要呢

使用 ? 来表示,这个时候我们`person`对象上的`sayHi`方法就可以随意使用

type Person = {
        name: string
        sayHi:(type:string,total?:string)=>void
}
person.sayHi('type');

👉Array数组类型

Array: 表示数组类型,可以通过 number[]Array<number> 来表示。

let nums: number[] = [1, 2, 3];
let strs: Array<string> = ["a", "b", "c"];

👉Tuple元组

项目中可能要使用到地图,涵盖经纬度

正常情况下我们的经纬度是这样子的:
let mapsition: number[] = [116.2317, 39.5427]
console.log(mapsition,'mapsition');

但是上面的方式没办法限制我们有几个经纬度,三个肯定错误的

这个时候就用到了元组 Tuple


规定两个数字类型的:
let mapsition:[number, number] = [116.2317, 39.5427]

可以看出,元组类型可以确切地标记出有多少个元素,以及每个元素的类型

Tuple: 元组类型,表示一个固定长度的数组,其中每个元素的类型可以不同。
let person: [string, number] = ["Alice", 25];

👉枚举enum

枚举的功能类似于字面量类型+联合类型组合的功能

Enum: 枚举类型,表示一组命名的常量。
enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}
let dir: Direction = Direction.Up;
 // 创建枚举
enum Direction { Up, Down, Left, Right }

// 使用枚举类型
function changeDirection(direction: Direction) {
    console.log(direction)
}

// 调用函数时,需要应该传入:枚举 Direction 成员的任意一个
// 类似于 JS 中的对象,直接通过 点(.)语法 访问枚举的成员
changeDirection(Direction.Right)

也就是说枚举其实是定义一组命名常量,然后界定在其中一个呗。

如果有个初始值,如何在枚举之中给这些值赋值一个初始值呢

 // 创建枚举
enum Direction { Up=2, Down=4, Left, Right }
// 使用枚举类型
function changeDirection(direction: Direction) {
    console.log(direction)
}
// 调用函数时,需要应该传入:枚举 Direction 成员的任意一个
// 类似于 JS 中的对象,直接通过 点(.)语法 访问枚举的成员
changeDirection(Direction.Right)

数字枚举和字符串枚举有什么不同呢

字符串枚举必须是有初始值
 
// 注意:字符串枚举没有自增长行为,因此,字符串枚举的每个成员必须有初始值
enum Direction {
    Up = 'UP',
    Down = 'DOWN',
    Left = 'LEFT',
    Right = 'RIGHT'
}
// 使用枚举类型
function changeDirection(direction: Direction) {
    console.log(direction)
}
// 调用函数时,需要应该传入:枚举 Direction 成员的任意一个
// 类似于 JS 中的对象,直接通过 点(.)语法 访问枚举的成员
changeDirection(Direction.Right)
整个演变过程编译   =>  被编译为以下 JS 代码:

var Direction;
(function (Direction) {
  Direction['Up'] = 'UP'
  Direction['Down'] = 'DOWN'
  Direction['Left'] = 'LEFT'
  Direction['Right'] = 'RIGHT'
})(Direction || Direction = {})

也就是说枚举也是给定的多选一

函数类型

Function: 用于表示函数类型,指定函数参数和返回值类型。
let add: (a: number, b: number) => number = (a, b) => a + b;

👉object函数类型

就是函数参数和返回值加了一个类型

简单写个函数,然后我们调用一下

const handleTs = (numA,numB) => {
    console.log(numA,numB,'numA,numB');
}
handleTs(1,2);

1 2 'numA,numB'

接下来我们加个约束类型:

  const handleTs = (numA:number,numB:number) => {
    console.log(numA,numB,'numA,numB');
    return numA+numB;
  }

加个返回值的约束类型:

const handleTs = (numA:number,numB:number) : number => {
    console.log(numA,numB,'numA,numB');
    return numA+numB;
  }
 let total=handleTs(1,2);
 console.log(total,'total');

再抽离出来添加类型别名

type TsTotal = (numA:number,numB:number) => number
const handleTs:TsTotal =(numA,numB) =>{
console.log(numA,numB,'numA,numB');
return numA+numB;
}
let total=handleTs(1,2);
console.log(total,'total');

上面就是我们函数有返回值时候的写法

那么没有返回值呢? 这个时候就需要用到void 类型

const handleTs  =(numA:number): void =>{
  console.log(numA,'numA');
}
let total=handleTs(1);
console.log(total,'total');

当然了,void和不写时候也是一样的。

也就是说下面的两种写法其实都是一样的

//什么都不写,返回值类型为: void
const handleTs = () => {}

// 指定函数返回值类型为 void
const handleTs = (): void => {}

指定返回值类型为 undefined的情况

// 指定返回值类型为 undefined,函数体中必须显示的 return undefined 才可以
 const handleTs = (): undefined => {
        // 此处,返回的 undefined 是 JS 中的一个值
        return undefined
}
let data = handleTs();
console.log(data, 'data');

// 输出
undefined 'data'

有时候我们函数之中的参数不一定都是必须要传的

参数可以传也可以不传 这个时候用到的可选参数

  • 可选参数:在可传可不传的参数名称后面添加 ?(问号)

比如我们上面的函数可以更改为:

// 函数可选参数
const handleTs =(numA?:number,numB?:string):string =>{
  console.log(numA,numB,'numA,numB');
  return numB?numA+numB:numA+'';
}
let total=handleTs(1,'2');
console.log(total,'total');

需要注意的是:可选参数只能出现在参数最后,也就是说可选参数后面不能再出现必选参数

👉void空

void: 表示函数没有返回值,通常用于没有返回值的函数。
function greet(): void {
  console.log("Hello!");
}
void 0;// undefined
function hello(): void {
    console.log('hello typescript');
}

👉never

never: 表示一个永远不会正常结束的函数(比如抛出异常或无限循环)。
function throwError(): never {
  throw new Error("An error occurred");
}
function error(message: string): never {
     throw new Error(message);
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。