类型断言
类型断言可以用来手动指定一个值的类型,即允许变量从一种类型改为另一种类型。通俗来讲就是我相信我自己在定义什么类型
语法:
<类型>值
值 as 类型
export default {};
// 方法一
let str1 = "阿斯顿法国红酒看来阿斯顿法国红酒看来";
let len1 = (<string>str1).length;
console.log(len1); //18
// 方法二
let str2 = "阿桑的歌回家看了";
let len2 = (str2 as string).length;
console.log(len2); //8
// 定义一个方法传入字符串则返回字符串的长度,传入数字则返回数字
function getLen(x: number | string) {
if (typeof x == "string") {
return (str2 as string).length;
} else {
return x;
}
}
console.log(getLen("araqw")); //8
console.log(getLen(123)); //123
type别名
类型别名就是给一个类型其一个新名字,但他们都代表同一个类型
例如:张三 他的外号是法外狂徒,小名狗蛋, 狗蛋和法外狂徒都表示是张三
export default {};
// 第一种 变量
type name = "张三" | "法外狂徒" | "狗蛋";
// let stu1:name = "李四" //报错 不能将李四赋值给stu1
let stu1: name = "张三"; //正常
console.log(stu1); //张三
let stu2: name = "法外狂徒";
console.log(stu2); //法外狂徒
// 第二种 函数
type fun = (a: number, b: number) => number;
let fn: fun = (a: number, b: number) => a + b;
console.log(fn(10, 20)); //30
// 第三种 对象 键的value值只能是所设定的数据类型 如不按照数据类型赋值则报错
type obj = {
name: string;
age: number;
eat: boolean;
};
let stu3: obj = {
name: "赵四",
age: 20,
eat: false,
};
console.log(stu3); //{ name: '赵四', age: 20, eat: false }
接口
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法
格式:interface interface_name{} //建议接口名首字母为I(大写i)
export default {};
// 创建一个接口
interface INames {
firstName: string;
secondName: string;
}
// 创建一个姓名对象
let names: INames = {
firstName: "张三",
secondName: "李四",
};
console.log(names.firstName, names.secondName); //张三 李四
function say({ firstName, secondName }: INames): void {
console.log(`第一个人的名字是${firstName},第二个人的名字是${secondName}`); //第一个人的名字是张三,第二个人的名字是李四
}
say(names);
可选属性与只读属性
区别:作为变量使用的话用const,若作为属性则使用readonly
可选属性: ?
export default {};
// 可选属性
interface IStudent {
name: string;
sex: string;
age?: number;
}
let stu1: IStudent = {
name: "张三",
sex: "男",
// age:20,//可选属性 可写可不写 不会报错
};
let stu2: IStudent = {
name: "李四",
sex: "男",
age: 20, //可选属性 可写可不写 不会报错
};
console.log(stu1, stu2); //{ name: '张三', sex: '男' } { name: '李四', sex: '男', age: 20 }
只读属性
// 只读属性
interface IInfo {
readonly uName: string;
readonly uAge: number;
}
let user1: IInfo = {
uName: "张三",
uAge: 20,
};
console.log(user1); //{ uName: '张三', uAge: 20 }
// user1.uName = "赵六" //报错 无法赋值 因为是只读属性
索引签名
解决参数可多可少的问题
-
可选参数
-
使用变量 将变量赋给一个对象将对象传过去
-
类型断言
export default {};
// 解决参数可多可少的问题
// 少一个或多个问题 可选参数
interface IInfo {
name: string;
age?: number;
sex: string;
[props: string]: any; //索引签名 数据类型any任意
}
let stu1: IInfo = {
name: "张三",
age: 20,
sex: "男",
};
console.log(stu1); // { name: '张三', age: 20, sex: '男' }
let stu2: IInfo = {
name: "李四",
sex: "男",
};
console.log(stu2); //{ name: '李四', age: 21, sex: '男', hobby: '吃饭、睡觉、打豆豆' }
// 多一个或者多个解决方法
// 一、使用变量将变量赋值给一个对象将,对象传过去
let stuInfo = {
name: "赵六",
age: 20,
sex: "女",
};
let stu3: IInfo = stuInfo;
console.log(stu3); //{ name: '赵六', age: 20, sex: '女' }
// 二、使用类型断言 <类型>值 值 as 类型
let stu4: IInfo = { name: "王五", sex: "男", hobby: "打游戏" } as IInfo;
console.log(stu4); //{ name: '王五', sex: '男', hobby: '打游戏' }
let stu5: IInfo = <IInfo>{ name: "赵四", sex: "女", hobby: "打羽毛球" };
console.log(stu5); //{ name: '赵四', sex: '女', hobby: '打羽毛球' }
// 三、索引签名 对象中的键都会被转化为字符串
//主要设置在IInfo中的 [props: string]: any;
let stu6: IInfo = {
name: "王大拿",
age: 30,
sex: "男",
hobby: "唱歌、跳舞",
};
console.log(stu6); //{ name: '王大拿', age: 30, sex: '男', hobby: '唱歌、跳舞' }
函数接口
为了使用接口表是函数类型,我们需要给接口定义一个调用签名,
她就像是一个只有参数列表和返回值类型的函数定义,参数列表里的每个参数都需要名字和类型。
export default {};
// 创建一个函数接口
interface ISum {
(num1: number, num2: number): number;
}
// 创建函数
let sum: ISum = function (x: number, y: number): number {
return x + y;
};
// 调用函数并将返回结果赋值
let res = sum(20, 21);
console.log(res);
接口的继承
接口函数就是说接口可以通过其他接口来扩展自己
TypeScript允许接口继承多个接口
继承使用关键字extends
// 函数的继承 子承父业
interface IFather {
name: string;
age: number;
}
// 继承extends
interface ISon extends IFather {
hobby: string;
}
let stu1: ISon = {
name: "张三",
age: 20,
hobby: "唱歌、跳舞",
};
console.log(stu1.name, stu1.age, stu1.hobby); //张三 20 唱歌、跳舞
接口与类型别名的异同
相同点:
都可以描述属性或方法
都允许拓展
不同点:
type可以生命基本数据结构、联合类型、数组等;interface只能声明变量
当出现使用type和interface生命相同的数据时,type会直接报错;interface会进行合并
type不会自动合并;interface会自动合并
export default {};
// 相同点
// 1、都可以描述属性或方法
// 类型别名
type person = {
name: string;
age: number;
say(): any;
};
// 接口
interface IPerson {
name: string;
age: number;
say(): any;
}
let tP1 = {
name: "张三",
age: 20,
say: function () {
console.log(`我的姓名是${this.name}`);
},
};
let iP1 = {
name: "张三",
age: 20,
say: function () {
console.log(`我的姓名是${this.name}`);
},
};
console.log(tP1); //{ name: '张三', age: 20, say: [Function: say] }
console.log(iP1); //{ name: '张三', age: 20, say: [Function: say] }
// 2、都允许拓展
// 类型别名
type person1 = {
name: string;
};
type person2 = person1 & {
age: number;
};
// 接口
interface IPerson1 {
name: string;
}
interface IPerson2 extends IPerson1 {
age: number;
}
// 类型别名
let tP2: person2 = {
name: "李四",
age: 19,
};
// 接口
let iP2: IPerson2 = {
name: "李四",
age: 20,
};
console.log(tP2); //{ name: '李四', age: 19 }
console.log(iP2); //{ name: '李四', age: 20 }
// 不同点
// 1、type可以声明基本数据类型,联合类型,数组等
// interface只能声明变量
type age = number;
type info = string | number | boolean;
type beautiList = [string | boolean];
// interface Iage = number //直接报错
// 2、当出现使用type和interface生命同名的数据时
// type会报错
type person3 = {
name: string;
};
type person3 = {
name: string;
};
// interface会进行合并
interface IPerson3 {
name: string;
}
interface IPerson3 {
name: string;
}