本文介绍: # 约束对象– 一般使用 **[字面量]** 约束变量的类型为对象“`typescriptlet obj1: {}; // 约束该变量的类型为对象let obj2: { name: string }; // 约束该变量的类型为 [有且只有 name 属性的] 对象, 且 name 的属性值的类型必须是 string“`- 可以直接给变量赋值,TS 会自动识别类型,并对变量进行约束“`typescriptlet obj = { width: 200 }; // 此时 ob
约束对象
let obj1: {}; // 约束该变量的类型为对象
let obj2: { name: string }; // 约束该变量的类型为 [有且只有 name 属性的] 对象, 且 name 的属性值的类型必须是 string
let obj = { width: 200 }; // 此时 obj 的类型被约束为 { width: number }
可选属性
let obj: { name: string; age?: number }; // age 属性可选
let obj: { name?: string };
obj = { name: 'superman' };
console.log(obj.name?.toLocaleUpperCase()); // SUPERMAN
obj = {};
console.log(obj.name?.toLocaleUpperCase()); // undefined
其他属性
- 可以设置
[自定义属性名: string]: 指定类型
接收其他的属性
①string
– 约束 [属性名] 的类型为string
③[]
括住 – 表示 [其他属性] 可以有 0 ~ n 个 指定类型
– 需要兼容所有属性的类型
type Person = {
name: string;
say(): string; // say 函数; 返回值的类型为 string
[propName: string]: string | number; // 如果不确定 [其他属性] 的类型,可以约束为 any 类型
}; // 这种写法表示 name、age 属性必填, 其他属性可选
let obj: Person = { name: 'superman', age: 21, gender: 'male' };
console.log('obj', obj); // obj { name: 'superman', age: 21, gender: 'male' }
type MyArray1 = { [index: number]: string };
type MyArray2 = string[]; // MyArray1 与 MyArray2 等效
let arr1: MyArray1 = ["a", "b", "c"];
let arr2: MyArray2 = ["a", "b", "c"];
只读属性
type ReadonlyPerson = {
readonly age: number;
};
let readonlyPerson: ReadonlyPerson = { age: 20 };
// readonlyPerson.age++; // 直接飘红
type Person = {
readonly name: string;
age: number;
};
type Superman = {
readonly friend: Person;
};
let person: Person = { name: 'monster', age: 20 };
let superman: Superman = { friend: person };
console.log(superman); // { friend: { name: 'monster', age: 20 } }
superman.friend.age++;
// superman.friend.name = "superwomen"; // 直接飘红
console.log(superman); // { friend: { name: 'monster', age: 21 } }
type Person = {
age: number;
};
type ReadonlyPerson = {
readonly age: number;
};
let person: Person = { age: 20 };
let readonlyPerson: ReadonlyPerson = person;
console.log(readonlyPerson); // { age: 20 }
person.age++;
console.log(readonlyPerson); // { age: 21 }
type Person = {
name: string;
readonly [propName: string]: any;
};
let person: Person = { name: 'superman', age: 21 };
// person.age++; // 直接飘红
约束函数
let showSum: (num1: number, num2: number) => void; // 约束变量 fun 的类型为特定的函数
showSum = function (n1, n2) {
console.log(n1 + n2);
};
① num1
、num2
– 形参名,可随便自定义;表示 [有且只有 2 个参数]
② number
– 约束 [参数] 的类型为 number
③ void
– 约束 [返回值] 的类型为 undefined
-
注意:函数定义其返回值类型为
void
时,该函数不能返回除undefined
外的其他值但是,上下文函数类型定义其返回值类型为
void
时 (type VoidFun = () => void
)
该上下文函数可以返回任意值,但是返回值的类型还是会被约束成void
// 普通函数写法
function fun1(): void {
// return true; // 直接飘红
}
// 函数表达式写法 (匿名函数)
let fun2 = function (): void {
// return true; // 直接飘红
};
// 上下文函数类型定义
type VoidFun = () => void;
let fun3: VoidFun = () => true; // 返回 true
let res = fun3(); // res 被约束为 void 类型
console.log('res', res); // res true
可选参数
function formatNum(num?: number) {
console.log(num?.toFixed());
console.log(num?.toFixed(1));
}
formatNum(123.456); // 123 123.5
formatNum(); // undefined undefined
function showName(person?: { name: string }) {
console.log("name", person!.name); // 表示参数 person 一定会被传入
}
showName({ name: "superman" });
showName(); // 此时 执行代码会报错,因为没有传入参数 person
剩余参数
let buildName = (firstName: string, ...restOfName: string[]) =>
// 如果不确定剩余参数的类型,可以约束为 any[] 类型
// 此时 restOfName 会以数组的形式存储剩余的所有参数
`${firstName}-${restOfName.join('-')}`;
console.log(buildName('Huang', 'Shi', 'Jie')); // Huang-Shi-Jie
const args = [1, 2];
const sum = (num1: number, num2: number): number => num1 + num2;
// console.log(sum(...args)); // 直接飘红
// 因为 sum 只接收两个参数,而 args 自动被 TS 约束为数组,数组可能不只两个元素
解决办法 ①:显式约束 args
为 [有且只有 2 个元素的数组],即 [元组] 类型
解决办法 ②:使用 as const
将 args
约束为当前 [字面量]
const args: [number, number] = [1, 2];
const sum = (num1: number, num2: number): number => num1 + num2;
console.log(sum(...args));
const args = [1, 2] as const;
const sum = (num1: number, num2: number): number => num1 + num2;
console.log(sum(...args));
调用签名
// 注意:类型是对象的形式
type FunType = {
description: string; // 约束函数的 [属性]
(someArg: number): boolean; // 调用签名 - 约束函数的 [参数] & [返回值]
}; // 注意, 这里用的是 `(XX: XXX): XXX`,不是 `[XX: XXX]: XXX`
function fun(num: number): boolean {
return !!num;
}
fun.description = 'my function';
function showFun(fn: FunType, num: number) {
console.log(`${fn.description} return ${fn(num)}`);
}
showFun(fun, 0); // my function return false
showFun(fun, 1); // my function return true
构造签名
// 定义一个类
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
// 注意:类型是对象的形式
type FunType = {
new (s: string): Person; // 构造签名 - 约束构造函数的 [参数] & [返回值]
};
function createPerson(ctor: FunType) {
return new ctor('superman');
}
console.log(createPerson(Person)); // Person { name: 'superman' }
函数重载
// 参数类型不同
declare function fun(a: string): void;
declare function fun(a: number): void;
// 参数数量不同
declare function fun(n: number): void;
declare function fun(n: number, y: number): void;
// 参数类型的顺序不同
declare function fun(n: number, s: string): void;
declare function fun(s: string, n: number): void;
/* 声明 (重载函数) */
function add(arg1: string, arg2: string): string;
function add(arg1: number, arg2: number): number;
// 因为在下边有具体的函数实现,所以不需要添加 declare 关键字
/* 实现 (实现函数) */
function add(arg1: number | string, arg2: string | number): number | string {
if (typeof arg1 === 'number' && typeof arg2 === 'number') {
console.log('进行数值相加');
return arg1 + arg2;
} else {
console.log('进行字符串拼接');
return (arg1 as string) + (arg2 as string);
}
}
let addResult1 = add(10, 20); // addResult1 的类型为 number
let addResult2 = add('10', '20'); // addResult2 的类型为 string
// let addResult3 = add("10", 20); // 直接飘红,因为 [重载函数] 中没有允许这种类型的参数
/* 声明 (重载函数) */
function makeDate(timeStamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
/* 实现 (实现函数) */
function makeDate(timeStampOrM: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, timeStampOrM, d);
} else {
return new Date(timeStampOrM);
}
}
let addResult1 = makeDate(1661044053502);
let addResult2 = makeDate(8, 31, 2000);
// let addResult3 = makeDate(8, 31); // 直接飘红,[重载函数] 中没有允许这种类型的参数
- 在某些情况下,我们更偏向于使用联合类型
|
而不使用函数重载
/* 使用函数重载 */
function getLength(x: any[]): number;
function getLength(x: string): number;
function getLength(x: any): number {
return x.length;
}
// let addResult1 = getLength(Math.random() < 0.5 ? "superman" : [1, 2, 3]); // 直接飘红
// 因为 "大" 类型不能赋值给 "小" 类型
// 而参数的类型 `"superman" | number[]` 比 `any[]` 和 `string` 都要 "大"
/* 使用联合类型 `|` */
function getLength(x: any[] | string): number {
return x.length;
}
let addResult1 = getLength(Math.random() < 0.5 ? 'superman' : [1, 2, 3]); // 可以正常使用
关于对象类型的参数
interface Person {
name: string;
age?: number;
}
function showPerson({ name: string, age: number = 0 }: Person) {
// 使用解构赋值接收对象参数
// 此时,string、number 不是用于约束类型,而是属性的别名
console.log('name', string); // name superman
console.log('age', number); // age 0
}
showPerson({ name: 'superman' });
原文地址:https://blog.csdn.net/Superman_H/article/details/126455644
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_32290.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。