虹口专业网站建设,南昌有哪些企业网站,常见的手机网站,网站建设及第三方支付文章目录一、TypeScript高级类型1.1 class类1.2 class继承1.3 class类成员可见性1.4 readonly1.5 类型兼容性1.5.1 对象之间的类型兼容性1.5.2 接口之间类型兼容性1.5.3 函数之间类型兼容性1.6 交叉类型1.7 交叉类型()和继承(extends)的对比二、泛型2.1 泛型约束--指定更具…
文章目录一、TypeScript高级类型1.1 class类1.2 class继承1.3 class类成员可见性1.4 readonly1.5 类型兼容性1.5.1 对象之间的类型兼容性1.5.2 接口之间类型兼容性1.5.3 函数之间类型兼容性1.6 交叉类型1.7 交叉类型()和继承(extends)的对比二、泛型2.1 泛型约束--指定更具体的类型2.2 泛型约束--extends添加约束2.3 多个泛型变量2.4 泛型接口2.5 泛型类2.6 泛型工具类Parital\Type\2.7 泛型工具类Readonly\Type2.8 泛型工具类Pick\Type, Keys2.9 泛型工具类Record\Keys, Type三、索引签名类型四、映射类型一、TypeScript高级类型
1.1 class类
TypeScrtip全面支持ES2015中引入的class关键字并为其添加了类型注解和其他语句 class基本使用 TS中的class不仅提供了class的语法功能也作为一种类型存在
class Person {}
const p:Person new Person()实例属性初始化
class Person {name: string kangyun;gender 男;
}
const p: Person new Person();构造函数 构造函数为class类的实例属性初始化值的 构造函数不需要返回值
class Person {name: string;gender: string;constructor(name: string, gender: string) {this.name name;this.gender gender;}
}
const p: Person new Person(张三, 男);
/script类的实例方法
class Person {name: string;gender: string;constructor(name: string, gender: string) {this.name name;this.gender gender;}// 方法的类型注解(参数和返回值)与函数用法相同sayHello(name: string): void {console.log(hello,${name});}
}
const p: Person new Person(张三, 男);
p.sayHello(李四);1.2 class继承
类继承的两种方式:
extends(继承父类)implements(实现接口)
JS中只有extends而implements是TS提供的
class Animail {move() {console.log(Moving!);}
}class Dog extends Animail {bark() {console.log(汪汪......);}
}
// 子类Dog继承父类Animal则Dog的实例对象dog就同时具有了父类
// Animal和子类Dog的所有属性和方法
const dog: Dog new Dog();
dog.move();
dog.bark();interface Singable {name: string;sing: () void;
}
// Person类实现接口Singable就必须提供Singble接口中指定的方法和属性
class Person implements Singable {name 张三;sing() {console.log(开始黄牛叫了......);}
}1.3 class类成员可见性
可见性修饰符包括
public 公有的proected 受保护的private 私有的
public表示公共、公有的公有成员可以被任何地方访问 public: 是默认可见性所以可以直接少略
class Animal{public move(){console.log(moving!)}
}protected 表示受保护的仅对其所在类和子类中非实例对象可见 在子类的方法内部可以通过this来访问父类中受保护的成员但是对实例不可见
class Animal {protected move() {console.log(moving);}
}
class Dog extends Animal {bark() {console.log(汪汪......);this.move();}
}
const dog new Dog();
dog.bark();private: 表示私有的只在当前类中可见对实例对象以及子类也是不可见的
class Animal {private move() {console.log(moving);}walk(){this.move()}
}1.4 readonly
readonly表示只读用来防止在构造函数之外对属性进行赋值
class Animal {readonly age: number;constructor(age: number) {this.age age;}
}readonly只能修饰属性不能修饰方法接口或者{}表示的对象类型也可以使用readonly修饰
1.5 类型兼容性
两种类型系统
Structural Type System(结构化类型系统)Nominal Type System(标明类型系统) TS采用的是结构化类型系统类型检查关注的是值所具有的形状 在结构类型系统中如果两个对象具有相同的形状态则认为它们属性同一类型
class Point01{x: number, y: number}
class Point02{x: number, y: number}
const p:Poing01 new Point02()因为TS是结构化类型系统只检查Point01和Point02的结构是否相同相同都具有x和y两个属性属性类型也相同 但是如果在标明类型系统如c#和java中它们是不同的类类型无法兼容。
1.5.1 对象之间的类型兼容性
对于对象类型来说y的成员至少与x相同则x兼容y(成员多的可以赋值给少的)
class Point {x: number; y: number}
class Point3D {x: number; y:number: z:number}
const p:Point new Point3D()1.5.2 接口之间类型兼容性
接口之间的兼容性类似于class,并且class和interface之间也可以兼容
interface Point {x:number; y:number}
interface Point2D {x:number; y:number}
let p1: Point
let p2: Point2D p1
interface Point3D {x:number; y:number; z:number}
let p3:Point3D
p2 p31.5.3 函数之间类型兼容性
函数之间兼容性比较复杂需要考虑参数个数、参数类型、返回值类型 参数个数参数多的兼容参数少的或者说参数少的可以赋值给多的
type F1 (a:number)void
type F2 (a:number, b:number) void
let f1: F1
let f2: F2 F1参数少的可以赋值给参数多的所以f1可以赋值给f2数组forEach方法的第一个参数是回调函数该示例中类型为(value: string, index: number, array: string[])void在JS中省略用不到的函数参数实际是很常见的这样的使用方式促成了TS中函数类型之间的兼容性并且因为回调函数是有类型的所以TS会自动推导出参数item、index、array的类型
***参数类型***相同位置的参数类型要相同
type F1 (a:number) string
type F2 (a:number) string
let f1: F1
let f2: F2 F1函数类型F2兼容函数类型F1因为F1和F2的第一个参数类型相同。
interface P2D {x:number; y:number}
interface P3D {x:number; y:number; z:number}
type F2 (p:P2D)void
type F3 (p:P3D)void
left f2: F2
let f3: F3 f2技巧将对象拆开把每个属性看做一个一个的参数则参数少的f2可以赋值给参数多的f3。
返回值类型只关注返回值类型本身即可
type F5 () string
type F6 () string
let f5: F5
let f6: F6 f5type F7 () {name: string}
type F8 () {name: string, age: number}
let f7: F7
let f8: F8
// 返回的是对象对象多的可以赋值给少的
f7 f81.6 交叉类型
交叉类型()类似于接口继承用于组合多个类型为一个类型常用于对象类型
interface Person {name: string}
interface Contact {phone: string}
type PersonDetail Person Contact
let obj: PersonDetail {name: Bill,phone: 15220......
}使用交叉类型后新的类型PersonDetail就同时具备了Person和Contact的所有属性类型这和继承很相似。
1.7 交叉类型()和继承(extends)的对比
相同点都可实现对象类型的组合 不同点两种方式实现类型组合时对于同名属性之间处理类型冲突的方式不同。
interface A {fn:(value: number) string
}
interface B extends A {fn: (value: string) string
}上示代码接口继承会报错(类型不兼容)
interface A{fn:(value: number) string
}
interface B{fn:(value: string) string
)
type C A B
C的结果会是: fn:(value: number|string) string二、泛型
泛型是可以在保证类型安全前提下让函数等与多种类型一起工作从而实现复用常用于函数、接口、class中。 泛型是用来实现可复用组件功能的主要工具之一。
创建泛型函数
function idType(value: Type):Type { return value}PS 在函数名称后面添加尖括号尖括号中添加类型变量如此处Type,类型变量Type是一种特殊类型的变量它处理类型而不是值。该类型变量相当于一个类型容器能够捕获用户提供的类型具体是什么类型由用户调用该函数时指定。因为Type是类型因此可以将其作为函数参数和返回值的类型类型变量Type可以是任意合法的变量名称。
调用泛型函数
const num idnumber(10)
const str idstring(hello)PS: 当传入类型number后这个类型就能会被函数声明时指定的类型变量Type捕获到。这样通过泛型就做到了让id函数与多种不同的类型一起工作实现了复用的同时保证了类型安全。
简化调用泛型函数
function idType(value: Type):Type { return value}
let num01 idnumber(10)
let num02 id(10) //简化简化由TS类型参数推断当编译器无法推断类型或者推断的类型不准确时就需要显式地传入类型参数。
2.1 泛型约束–指定更具体的类型
***泛型约束***默认情况下泛型函数的类型变量Type可以代表多个类型这导致无法访问任何属性。 如id(‘a’)调用函数时获取参数的长度
function idType(value: Type): Type{console.log(value.length)return value
}PS: Type可以代表任意类型无法保证一定存在length属性如number就没有length,此时就需要为泛型添加约束来收缩类型。 指定更具体的类型
function idType(value: Type[]): Type[]{console.log(value.length)return value
}将类型Type修改为Type[](Type类型的数组),因为只要是数组就一定存在Length。
2.2 泛型约束–extends添加约束
添加约束
interface ILength{ length: number }
function idType extends ILength(value: Type): Type{console.log(value.length)return value
}PS: 通过extends关键字使用该接口为泛型类型变量添加约束该约束表示传入的类型必须具有length属性
2.3 多个泛型变量
泛型的类型变量可以有多个并且类型变量之间还可以约束。
// Key extends keyof Type
// Key的值必须是Type类的key
function getPropType, Key extends keyof Type(obj: Type, key: Key){reutnr obj[key]
}
let person {name: kk, age: 18 }
getProp(person, name)keyof关键字接收一个对象类型生成其键名称可能是字符串或数字的联合类型
2.4 泛型接口
泛型接口接口也可以配合泛型来使用以增加其灵活性增强复用性
interface IdFuncType{id: (value: Type) Typeids: () Type[]
}
let obj:IdFuncnumber{id(value){return value},ids(){ return [1, 2, 3] }JS中的数组在TS中就是一个泛型接口
const strs [a, b, c]2.5 泛型类
class GenericNumberNumberType{defaultValue: NumberTypeadd: (x: NumberType, y: NumberType) NumberType
}PS: 类似于泛型接口在class名称后添加类型变量这个类就成了泛型类add方法采用的是箭头函数形式书写方式。
const myNum new GenericNumbernumber()
myNum.defaultValue 102.6 泛型工具类ParitalType
泛型工具类ParitalType用来构造创建一个类型将Type的所有属性设置为可选。
interface Props {id: number,children: number[]
}
type ParitalProps ParitalPropsPS:构造出来的新类型ParitalProps结构和Props相同但所有属性都变为可选的。
2.7 泛型工具类ReadonlyType
泛型工具类ReadonlyType用来构造一个类型将Type的所有属性都设置为readonly(只读)
interface Props{id: stringchildren: number[]
}
type ReadonlyProps ReadonlyProps解释构造出来的新类型ReadonlyProps结构和Props相同但所有属性都变为只读
let props: ReadonlyProps {id: 1, children: [] }
props.id 2 //error重新给id属性赋值会报错因为它是只读属性。
2.8 泛型工具类PickType, Keys
泛型工具类PickType, Keys从Type中选择一组属性来构造新类型
interface Props{id: stringtitle: stringchildren: number
}
type PickProps PickProps, id|titlePick工具类型有两个类型变量
表示选择谁的属性表示要选择哪几个属性
构造出来的PickProps只有id和title两个属性类型。
2.9 泛型工具类RecordKeys, Type
泛型工具类RecordKeys, Type构造一个对象类型属性键为Keys属性类型为Type
type RecordObje Recorda|b|c, string[]
let obj: RecordObje {a: [a],b: [2],c: [aaa]
}PS: Record工具类型有两个类型变量 1、表示对象有哪些属性 2、表示对象属性的类型
三、索引签名类型
绝大多数情况下我们都可以在使用对象前就确定对象的结构并为对象添加准确的类型。 当无法确定对象中有哪些属性或者说对象中可以出现任意多个属性此时就用到索引签名类型了。
interface AnyObject{[key: string]: number
}
let obj: AnyObject {a: 1, b: 2,
}PS: 使用[key: string]来约束该接口中允许出现的属性名称。表示只要是string类型的属性名称都要以出现在对象中。 key只是一个占位符可以换成任意合法的变量名称。
四、映射类型
映射类型基于旧类型创建新类型对象类型
type PropKeys x | y | z
type Type1 { x:number; y: number; z: number }上例有太多重复的代码
type PropKeys x | y | z
type Type2 { [Key in PropKeys]: number}映射类型是基于索引签名类型的所以该语法类似于索引签名类型 映射类型只能在类型别名中使用不能在接口中使用
映射类型keyof 映射类型除了根据联合类型创建新类型外还可以根据对象类型来创建
type Props {a: number; b: string; c: boolean}
type Type { [key in keyof Props]: number }PS: 先执行keyof Props获取到对象类型Props中所有键的联合类型即’a’|‘b’|‘c’ 然后key in …就表示key可以是Props中所有的键名称中的任意一个
像泛型工具类型ParitalType这些都是基于映射类型实现的
type ParitalT {[P in keyof T]?: T[P]
}T[p]在TS中叫做查询访问类型 用来查询属性的类型
type Props {a: number; b: string; c: boolean}
type TypeA Props[a] // type TypeA number注意[]中的属性必须存在于被查询类型中否则就会报错。 索引查询类型的其他使用方式同时查询多个索引的类型
type Props {a: number; b: string; c: boolean}
type TypeA Props[a|b]使用字符串字面量的联合类型获取属性a和b对应的类型结果为string|number
type TypeA Props[keyof Props]使用keyof操作符获取Props中所有键对应的类型结果为number|string|boolean