类型别名 (type)
示例:
// ts 别名, 说白就是取一个别的名字
type numType = number | string;
let num:numType = 20;
console.log(num);
num = '1810A';
console.log(num);
// ts 别名, 说白就是取一个别的名字
type numType = { num: number | string };
let obj:numType = { num: 10 };
console.log(obj.num);
// num = '1810A';
// console.log(num);
交叉类型:交叉类型是将多个类型合并为一个类型。
示例:
// 交叉类型 & 则必须都要有
interface NameType{
obj: {
name: string
}
}
interface AgeType{
obj: {
age: number
}
}
type NameAgeType = AgeType & NameType;
const obj:NameAgeType = {
obj: {
name: '1810A',
age: 15
}
}
console.log(obj);
联合类型:联合类型与交叉类型很有关联,但是使用上却完全不同。
// 示例:
// 联合类型, 取其一即可
let num: number | string = 20;
console.log(num);
num = '1810A';
console.log(num);
类型推断:数据没有指定明确的类型,那么ts会按照类型推论的规则推断出一个类型
// 类型推断
let num = 10;
console.log(num);
num = '1810A';
console.log(num);
Unknown
- 顶级类型,它可以接收任何类型,但是无法赋值给其他类型(除 any 和 unknown 本身之外),因此在需要接收所有类型的场景下,优先考虑用 unknown 代替 any。
typeof
typeof 操作符可以用来获取一个变量的声明类型。
const jack = {
name: 'jack Ma',
age: 18,
};
type Person = typeof jack;
// { name: string, age: number }
const hello:string = 'hello world';
type Hello = typeof hello;
// string
keyof
keyof 操作符用来获取一个类型所有的键值,与 Object.keys 类似,前者获取 interface 的键,后者获取对象的键。
interface Person {
name: 'jack Ma',
age: 17,
}
type T1 = keyof Person;
// 'name' | 'age'
通常 keyof 会配合着 typeof 使用:
interface Person {
name: string,
age: number
}
function getPersonValue(obj:Person, key: keyof typeof obj): string|number {
return obj[key];
}
# 上面的 key 参数的类型 keyof typeof obj 值为 'name' | 'age',这样可以对 key 值进行约束,避免使用时 key 值拼写错误导致的错误。
in
- in 操作符通常用来实现枚举类型遍历 ```javascript type Keys = ‘name’ | ‘age’; type Person = {
[K in Keys]: any;
} // { name: any, age: any }
<a name="d59c3d53"></a>
# 装饰器(调用的关键字 @)
- 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。
-
1. 类装饰器
```javascript
示例:
function sealed(target) {
target.prototype.msg = '1810A';
target.prototype.getMsg = function() {
console.log(this.msg);
}
}
@sealed
class Greeter {
// greeting: string;
constructor(message: string) {
// this.greeting = message;
}
// greet() {
// return "Hello, " + this.greeting;
// }
}
const g:any = new Greeter('1810A');
// console.log(g);
g.getMsg();
- 装饰器工厂 ```javascript 示例:
// 装饰器 // 这就是装饰器工程 function sealed(msg: string) {// 这是一个装饰器工厂 return function(target) { // 这就是一个装饰器 target.prototype.msg = msg;
target.prototype.getMsg = function() {
console.log(this.msg);
} } }
// 类装饰器 // 调用 @getTarget
// 当前的这个装饰器加上() 代表的是装饰器工厂 @sealed(‘1810A-你们是最棒的’) class Greeter { // greeting: string; constructor(message: string) {
// this.greeting = message;
} // greet() { // return “Hello, “ + this.greeting; // } }
const g:any = new Greeter(‘1810A’); // console.log(g); g.getMsg(); ```
- 装饰器组合(多个装饰器可以同时应用到一个声明上,) ```javascript 示例:
// 书写在同一行上 @f @g x
// 书写在多行上 @f @g x
同样的,在TypeScript里,当多个装饰器应用在一个声明上时会进行如下步骤的操作:
- 由上至下依次对装饰器表达式求值。
- 求值的结果会被当作函数,由下至上依次调用。
function f() { console.log(“f(): evaluated”); // 1 return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f(): called"); // 4
} }
function g() { console.log(“g(): evaluated”); // 2 return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g(): called"); // 3
} }
class C { @f() @g() method() {} }
输出结果 f(): evaluated g(): evaluated g(): called f(): called
注: 会先执行装饰器工厂,依次执行完所有的装饰器工厂之后,再从最内层的装饰器进行依次执行
```
- 方法装饰器(方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。) ```javascript
方法装饰会在运行时传入下列3个参数: 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2、成员的名字。 3、成员的属性描述符{value: any, writable: boolean, enumerable: boolean, configurable: boolean}。
function method(target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log(target); console.log(“prop “ + propertyKey); console.log(“desc “ + JSON.stringify(descriptor) + “\n\n”); };
class Hello{ name: string; age: number; constructor() { console.log(‘hello’); this.name = ‘yugo’; }
@method hello(){ return ‘instance method’; }
@method static shello(){ return ‘static method’; } } ```
- 访问器装饰器(访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。) ```javascript 示例:
访问器装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
- 成员的名字。
- 成员的属性描述符。
function configurable(value: boolean) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
}; }
class Point { private _x: number; private _y: number; constructor(x: number, y: number) { this._x = x; this._y = y; }
@configurable(false)
get x() { return this._x; }
@configurable(false)
get y() { return this._y; }
} ```
- 属性装饰器(属性装饰器声明在一个属性声明之前(紧靠着属性声明)。)
- 参数装饰器(参数装饰器声明在一个参数声明之前(紧靠着参数声明)。)