类型断言 可以把一个联合类型指定为一个更具体的类型。
```javascript
let name3: string | number;
console.log((name3 as string).toLowerCase())
```
字面量类型值的联合
只能赋值 这几个类型。
```javascript
let jinhua: 1 | 2 | 3 | 'honghong';
jinhua = 1;
jinhua = 2;
jinhua = 'honghong';
function getSomething(): string | number {
return 'jinhua' | 20;
}
```
#### 类
类里面的特性有
pubilc 公共的 所有地方都可以访问。
protect 受保护的 自己和自己孩子都能访问,外人不能访问。
private 私有的 自己能访问,自己孩子和外人不能访问。
```javascript
class Father {
public name: string;
protected age: number;
private money: number;
constructor(name: string, age: number, money: number) {
this.name = name;
this.age = age;
this.money = money;
}
getName() {
return this.name;
}
getAge() {
return this.age;
}
}
```
or
```javascript
class Father {
constructor(public name: string,protected age: number, private money: number) {
}
}
```
#### 类的类型
类型 type
当写一个类的时候,其实得到二个类型。
第一个类型就是,实例的类型。
第二个类型就是构造函数类型。
```javascript
class Person {
name: string;
}
let p: Person = {name: 'jin hua'};
type PersonType = type Person;
let p2: PersonType = Person;
```
## ts 装饰器 (decorators)
#### 说明
装饰器 是一种特殊类型的声明。
它能够被附加到类声明、方法、属性 或 参数上,可以修改类的行为。
常见的类装饰器有 类装饰器、属性装饰器、方法装饰器件 或 参数装饰器。
装饰器的方法主要有 普通装饰器 和 装饰器工厂。
#### 类装饰器件
类装饰器在类声明之前声明,用来监视、修改和替换类定义。
装饰器其实是一个函数。
targert 是传入的类。
```javascript
function decorators(targert: any) {
targert.prototype.name = 'jinhua';
targert.prototype.getName = function() {
return this.name;
};
}
@enhancer
class Person {
}
let p: Person = new Person();
console.log(p.name)
```
#### 属性装饰器
类装饰有两个参数,第一个是 原型对象,第二个是 键名。
```ts
function upperCase(target: any, name: string) {
}
class Person {
@upperCase
name: string = 'jin hua'
}
```
#### 方法装饰器
当装饰的是一个类的实现方法的时候。
target 类的原型, methodName 方法名,descriptor 属性描述器({get, set, enumerable, configurable, writable})
```ts
function noEnumerable(targert: any, methodName: string, descriptor: any) {
descriptor.enumerable = false;
}
class Person {
@noEnumerable
getName() {
console.log(this.name)
}
}
```
#### 参数装饰器
待定
```
1. 参数装饰器,从最后一个向前 依次执行。
2. 方法 和 方法参数中的装饰器,先执行 方法装饰器。
3. 类装饰器 总是最后执行。
4. 方法和属性装饰器件,谁在前谁先执行。
```
#### type
type 是类型泛型 类型的别名。
别名的作用域范围比较小。
1、 泛型别名可以表的更为复杂。
```ts
type Person<T> = {list:T[]} | T[];
let student: Person<string> = {list:['jin hua']};
let son: Person<number> = [22, 10000]
```
2、 interface 才是真正的类型,创建一个真实的类型名称,可以在任何地方被调用。然而,类别别名则不能被创建。比如,报错的时候就不能用。
3、 类型别名不能被继承和实现(extends 和 implements),如果要 extends 和 implements 必须用interface。
4、当需要用联合类型时,可以用别名。
```ts
// {a: [], b: []}
interface obj {
a: any[],
b: any[]
}
```
## 兼容性
#### interface 兼容性
如果传入的变量和声明的类型不匹配,TS就会进行兼容性检查
原理是Duck-Check,就是说只要目标类型中声明的属性变量在源类型中都存在就是兼容的
```ts
interface Animal{
name:string;
age:number;
gender:number
}
let a1 = {
name:'zhufeng',
age:10,
gender:0
}
interface Person {
name:string;
age:number
}
////- 要判断目标类型`Person`是否能够兼容输入的源类型`Animal`
function getName(p:Person):string{
return p.name;
}
getName(a1);
//只有在传参的时候两个变量之间才会进行兼容性的比较,赋值的时候并不会比较,会直接报错
let x:Person = {
name:'zhufeng',
age:10,
gender:0
}
```
#### 基本类型兼容性
```ts
//基本数据类型也有兼容性判断
let num : string|number;
let str:string;
num = str;
//只要有toString()方法
let num2 : {
toString():string
}
let str2:string;
num2 = str2;
```
#### calss 兼容性
类的兼容性,重要的是属性。
```ts
class Person {
name: string
}
class Son extends Person{
}
```
#### function 兼容性
函数的参数只能多不能少。
返回值属性只能多不能少。
```ts
type getName = () => {name: string, age: number}
function S1() {
return {name: 'S1', age: 10}
}
function S2() {
return {name: 'S2', age: 20, sex: 0}
}
let s0;
s0 = S1;
s0 = S2;
```
#### 函数参数的双向斜变
当比较函数参数的类型时,只有当源函数参数能够 赋值目标函数 或者反过来才能成功。
strickFunctionTypes