TypeScript接口、type关键字可读、只读属性、继承接口|类、规范类、函数|可索引|类|混合类型接口、ReadonlyArray、接口和amp;type、映射类型
目录
TypeScript接口
用于规范定义变量的类型,规定变量应该具有什么属性或函数入参什么值返回什么值等。
-
interface IUser {
-
name: string
-
age: number
-
}
-
let user: IUser = { name : 'yf', age: 32 }
可选属性
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?
符号。定义的属性可以不用实现。
-
interface IUser {
-
name: string
-
age?: number
-
}
-
let user: IUser = { name : 'yf' }
:?
注意区分冒号后也可以接问号。
-
const gender: ?number = undefined;
-
// 等同于下面这种写法
-
const gender: number | null | void = undefined
只读属性
只读属性只能在对象刚刚创建的时候修改其值。 在属性名前用readonly
来指定只读属性 。
-
interface Point {
-
readonly x: number;
-
readonly y: number;
-
}
-
let p1: Point = { x: 10, y: 20 };
-
p1.x = 5; // error!
ReadonlyArray<T>
表示数组创建后再也不能被修改
-
let a: number[] = [1, 2, 3, 4];
-
let ro: ReadonlyArray<number> = a;
-
ro[0] = 12; // error!
-
ro.push(5); // error!
-
ro.length = 100; // error!
-
a = ro; // error!
注意最后a=ro,将ReadonlyArray
赋值到一个普通数组也是不可以的。 但是你可以用类型断言重写
a = ro as number[];
接口继承接口(extends)
一个接口可以继承多个接口,创建出多个接口的合成接口,继承的每个接口里的内容都需要满足。
-
interface Shape {
-
color: string;
-
}
-
interface PenStroke {
-
penWidth: number;
-
}
-
interface Square extends Shape, PenStroke {
-
sideLength: number;
-
}
-
let square:Square = {
-
color: 'bule',
-
sideLength: 0,
-
penWidth: 0
-
};
接口继承类(extends)
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。
例如下面接口继承了Control类,故接口约束的abc类中需要定义pubulic的state属性
-
class Control {
-
state: any;
-
}
-
interface SelectableControl extends Control {
-
select(): void;
-
}
-
class abc implements SelectableControl {
-
state: any
-
select() { }
-
}
注意接口也能继承到类的private和protected成员。但继承后这个接口类型只能被这个类或其子类所实现。
例如下面abc实现SelectableControl接口就必须是Control类的子类,因为state属性是私有属性。
-
class Control {
-
private state: any;
-
}
-
interface SelectableControl extends Control {
-
select(): void;
-
}
-
-
class abc extends Control implements SelectableControl {
-
select() { }
-
}
接口规范类(implements)
相当于用接口规范便量时的冒号:,同样也可以通过逗号用多个接口约束一个类。
注意接口中定义的属性,必须在初始时定义,如果仅在constructor中定义也会报错,例如下面h不能仅在constructor中定义
-
interface ClockInterface {
-
tick();
-
}
-
interface Clock {
-
h: number
-
}
-
class DigitalClock implements ClockInterface,Clock {
-
//h: string //放开此行注释为正确的
-
constructor(h: number, m: number) { } //error缺少h属性
-
tick() {
-
console.log("beep beep");
-
}
-
}
函数类型接口
括号里为参数,冒号右边为函数的返回值。
函数的参数会逐个进行检查,只要求对应位置上的参数类型是兼容的。所以函数的参数名不需要与接口里定义的名字相同。
-
interface SearchFunc {
-
(source: string, subString: string): boolean;
-
}
-
let mySearch: SearchFunc = function(so: string, su: string) {
-
let result = so.search(su);
-
return result > -1;
-
}
可索引类型接口
可索引类型具有一个索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。
它共有支持两种索引签名:字符串和数字。
注意同时使用两种类型的索引时,数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用number
来索引时,JavaScript会将它转换成string
然后再去索引对象。 也就是说用100
(一个number
)去索引等同于使用"100"
(一个string
)去索引,因此两者需要保持一致。
-
class Animal {
-
name: string;
-
}
-
class Dog extends Animal {
-
breed: string;
-
}
-
interface NotOkay {
-
[x: number]: Animal;
-
[x: string]: Dog;
-
}// 错误:使用'string'索引,有时会得到Animal,数字索引应该是字符串索引的子集
-
-
interface NotOkay {
-
[x: number]: Dog;
-
[x: string]: Animal;
-
}//OK
注意使用了可索引类型后,另外定义的属性需要符合可索引。例如下面额外定义了字符串name属性,而使用的可索引也是字符串,所以指向的值应该相同。
-
interface NumberDictionary {
-
[index: string]: number;
-
length: number; // 可以,length是number类型
-
name: string // 错误,`name`的类型与索引类型返回值的类型不匹配
-
}
只读设置
可以将索引签名设置为只读,这样就防止了给索引赋值
-
interface ReadonlyStringArray {
-
readonly [index: number]: string;
-
}
-
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
-
myArray[2] = "Mallory"; // error!
类类型接口
接口描述了类的公共部分,而不是公共和私有两部分。 它不会检查类是否具有某些私有成员。
-
interface ClockInterface {
-
currentTime: Date;
-
}
-
-
class Clock implements ClockInterface {
-
private currentTime: Date;//error ,只能为public
-
constructor(h: number, m: number) { }
-
}
规定构造函数
注意类是具有两个类型的:静态部分的类型和实例的类型 , constructor存在于类的静态部分,所以不在检查的范围内。
故下面通过在接口里new定义构造函数会报错
-
interface ClockConstructor {
-
new (hour: number, minute: number);
-
}
-
-
class Clock implements ClockConstructor { //error,接口中的new无法直接在类里面实现
-
currentTime: Date;
-
constructor(h: number, m: number) { }
-
}
但是我们可以借助函数的的形式去实现,例如下面
-
interface ClockInterface {
-
tick();
-
}
-
class DigitalClock implements ClockInterface {
-
constructor(h: number, m: number) { }
-
tick() {
-
console.log("beep beep");
-
}
-
}
-
class AnalogClock implements ClockInterface {
-
constructor(h: number, m: number) { }
-
tick() {
-
console.log("tick tock");
-
}
-
}
-
interface ClockConstructor {
-
new (hour: number, minute: number): ClockInterface;
-
}
-
function createClock(ctor: ClockConstructor, hour: number, minute: number){
-
return new ctor(hour, minute);
-
}
-
let digital = createClock(DigitalClock, 12, 17);
-
let analog = createClock(AnalogClock, 7, 32);
混合类型接口
一个对象可以同时做为函数和对象使用,并带有额外的属性。
需要借助类型断言,例如下面:
-
interface Counter {
-
(start: number): string;
-
interval: number;
-
reset(): void;
-
}
-
function getCounter(): Counter {
-
let counter = <Counter>function (start: number) { };
-
counter.interval = 123;
-
counter.reset = function () { };
-
return counter;
-
}
-
-
let c = getCounter();
-
c(10);
-
c.reset();
-
c.interval = 5.0;
type关键字
用于给类型起一个新名字,支持基本类型、联合类型、元祖及其它任何你需要的手写类型,常用于联合类型。
-
type test = number; //基本类型
-
let num: test = 10;
-
type userOjb = {name:string} // 对象
-
type getName = ()=>string // 函数
-
type data = [number,string] // 元组
-
type numOrFun = Second | getName // 联合类型
type扩展(&)
interface的扩展可以通过type交叉(&)类型实现。
-
type Name = {
-
name: string;
-
}
-
type User = Name & {age: number}
-
let stu:User={name: 'wang', age: 18}
interface交叉(&)可以实现type类型。
-
interface Name {
-
name: string;
-
}
-
type User = Name & {
-
age: number;
-
}
-
let stu:User={name:'wang', age: 18}
interface继承type
接口可以继承type类型。
-
type Name = {
-
name: string;
-
}
-
interface User extends Name {
-
age: number;
-
}
-
let stu:User={name: 'wang', age: 89}
映射类型
type可以使用关键字生成映射类型。
-
type Keys = "name" | "sex"
-
type DuKey = {
-
[Key in Keys]: string //类似 for ... in
-
}
-
let stu: Dukey = {
-
name: 'wang',
-
sex: 'man'
-
}
type高级使用
补充:
-
// 将所有属性变成可选的
-
type Optional<T> = {
-
[key in keyof T]?: T[key];
-
}
-
-
// 将某些属性变成必选的
-
type MyRequired<T, K extends keyof T> = T &
-
{
-
[key in K]-?: T[key];
-
};
-
-
// 例如我们有个实体
-
type App = {
-
_id?: string;
-
appId: string;
-
name: string;
-
description: string;
-
ownerList: string[];
-
createdAt?: number;
-
updatedAt?: number;
-
};
-
-
// 我们在更新这个对象/类型的时候,有些 key 是必填的,有些 key 是选填的,这个时候就可以这样子生成我们需要的类型
-
type AppUpdatePayload = MyRequired<Optional<App>, '_id'>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgghafg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13