加入QQ群:864680898,一起学习进步!点击群名可查看本人网站,有最新文章!
(二)Typescript的核心Interface
在日常开发中会遇到很多在数据类型上不一致导致的错误,接口的作用就是规范你的代码与第三方的类型统一
函数形参类型限制
函数的形参限制其实就是它的原理
let add = (a: number, b: number):number=>a+b;
add(1, 1); // Ok
add(1,'1'); // Error
接口interface的使用
interface User{
name: string,
age: number,
location: string,
isAuthor: boolean
}
let showInfo = (user: User)=>console.log(user)
showInfo({ name: 'mySkey', age: 23, location: '成都', isAuthor: true }) // Ok
// 其中属性少传或者属性错误都会出错
showInfo({ name: 'mySkey' }) // Error
showInfo({ name: 23, age: 23, location: 23, isAuthor: 23 }) // Error
可选属性
接口里的属性不全都是必需的,即给函数传入的参数对象中只有部分属性赋值了。那么我不传入部分属性也不会出错,但是数据类型还是必须一致
interface User{
name?: string,
age?: number,
location: string,
isAuthor: boolean
}
let showInfo = (user: User)=>console.log(user)
showInfo({ location: '成都', isAuthor: true }) // Ok
只读属性
1、有的属性是不希望它被更改的,那么可以把它设置成只读 readonly
interface User{
readonly name: string,
readonly age: number,
location: string,
isAuthor: boolean
}
let user: User = { name: 'mySkey', age: 23, location: '成都', isAuthor: true };
console.log(user); // Ok
// 要更改时就会报错,没有定只读属性的就不会
user.name = 'boss'; // Error
user.location = '北京'; // Ok
2、具有ReadonlyArray类型,它与Array相似,可以保证数组被创建之后无法被更改
let a: number[] = [1,2,3,4];
let arr: readonlyArray<number> = [1,2,3,4];
arr[1] = 22; // Error
arr.push(22); // Error
// 而且作为值赋予给变量也不行
a = arr; // Error
// 但是可以用类型断言重写
a = arr as number[];
3、const vs readonly最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用const,若做为属性则使用readonly
额外属性
首先额外属性和只读属性不是一回事,只读属性是定义的属性可传可不传,额外属性是未被定义在interface中的属性,但是还是需要传进去
interface User{
readonly name: string,
readonly age: number,
location: string,
isAuthor: boolean
}
let user: User = { name: 'mySkey', age: 23, location: '成都', isAuthor: true, price: 33 }; // Error 未定义price属性
- 1、添加额外属性的方法一:利用类型断言
interface User{
readonly name: string,
readonly age: number,
location: string,
isAuthor: boolean
}
let user = ({ name: 'mySkey', age: 23, location: '成都', isAuthor: true, price: 33 } as User);
console.log(user)
- 2、方法二:添加一个字符串索引签名,前提是你能够确定这个对象可能具有某些做为特殊用途使用的额外属性
interface User{
readonly name: string,
readonly age: number,
location: string,
isAuthor: boolean,
[propName: string]: any;
}
let user: User = { name: 'mySkey', age: 23, location: '成都', isAuthor: true, price: 33 };
console.log(user)
- 3、方法三:用一个不用检测变量来赋值,当然就违背了我们使用typeScript的初衷
interface User{
readonly name: string,
readonly age: number,
location: string,
isAuthor: boolean,
[propName: string]: any;
}
let err = { name: 'mySkey', age: 23, location: '成都', isAuthor: true, price: 33 };
let user: User = err;
console.log(user)
函数类型
接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型
interface Add{
(a: number, b: number): number
}
let add:Add = (a,b)=>a+b
console.log(add(1,2))
对于函数检测的参数名可以与接口中检测的参数名不一致,但是数据类型必须一致
interface Add{
(num1: number, num2: number): number
}
let add:Add = (a,b)=>a+b
console.log(add(1,2))
类的类型
使用 implements 来绑定接口interface
interface PersonConstructor {
new (name: string, age: number): PersonInterface; // 实例部分的interface
}
interface PersonInterface {
position: string; // 静态部分的interface
setDate(d: Date): any;
}
let createConstructor = (ctor:PersonConstructor, name: string, age: number): PersonInterface =>{
return new ctor(name, age);
}
class Person implements PersonInterface{
position = '成都';
constructor(name: string, age: number){}
setDate(d: Date){
console.log(d)
}
}
let mySkey = createConstructor(Person, 'mySkey', 23);
console.log(mySkey.position)
mySkey.setDate(new Date('2018-04-05'))
扩展接口
和类一样,接口也可以相互扩展
interface FatherInterface {
surname: string; // 中国的姓氏
shape: string; // 外貌,孩子要是不像父亲。。。。。。
}
interface SonInterface extends FatherInterface {
isClever: boolean;
}
let son: SonInterface = { surname: 'deng', shape: 'cool', isClever: true }
而且一个接口可以继承多个接口,就像一个孩子继承了父亲,母亲,爷爷,奶奶······
interface FatherInterface {
surname: string; // 中国的姓氏
shape: string; // 外貌,孩子要是不像父亲。。。。。。
}
interface MathorInterface {
isCareful: boolean
}
interface SonInterface extends FatherInterface, MathorInterface {
isClever: boolean;
}
let son: SonInterface = { surname: 'deng', shape: 'cool', isCareful: false, isClever: true }
接口继承类
接口同样会继承到类的private和protected成员
class Father {
private surname: any;
public shape: string = '';
}
interface SonInterface extends Father{
}
class Son extends Father{
shape = 'cool'
}
let son = new Son();
console.log(son.shape) // cool