类型别名 (type)

  1. 示例:
  2. // ts 别名, 说白就是取一个别的名字
  3. type numType = number | string;
  4. let num:numType = 20;
  5. console.log(num);
  6. num = '1810A';
  7. console.log(num);
  8. // ts 别名, 说白就是取一个别的名字
  9. type numType = { num: number | string };
  10. let obj:numType = { num: 10 };
  11. console.log(obj.num);
  12. // num = '1810A';
  13. // console.log(num);

交叉类型:交叉类型是将多个类型合并为一个类型。

  1. 示例:
  2. // 交叉类型 & 则必须都要有
  3. interface NameType{
  4. obj: {
  5. name: string
  6. }
  7. }
  8. interface AgeType{
  9. obj: {
  10. age: number
  11. }
  12. }
  13. type NameAgeType = AgeType & NameType;
  14. const obj:NameAgeType = {
  15. obj: {
  16. name: '1810A',
  17. age: 15
  18. }
  19. }
  20. console.log(obj);

联合类型:联合类型与交叉类型很有关联,但是使用上却完全不同。

  1. // 示例:
  2. // 联合类型, 取其一即可
  3. let num: number | string = 20;
  4. console.log(num);
  5. num = '1810A';
  6. console.log(num);

类型推断:数据没有指定明确的类型,那么ts会按照类型推论的规则推断出一个类型

  1. // 类型推断
  2. let num = 10;
  3. console.log(num);
  4. num = '1810A';
  5. console.log(num);

Unknown

  • 顶级类型,它可以接收任何类型,但是无法赋值给其他类型(除 any 和 unknown 本身之外),因此在需要接收所有类型的场景下,优先考虑用 unknown 代替 any。

typeof

  • typeof 操作符可以用来获取一个变量的声明类型。

    1. const jack = {
    2. name: 'jack Ma',
    3. age: 18,
    4. };
    5. type Person = typeof jack;
    6. // { name: string, age: number }
    7. const hello:string = 'hello world';
    8. type Hello = typeof hello;
    9. // string

keyof

  • keyof 操作符用来获取一个类型所有的键值,与 Object.keys 类似,前者获取 interface 的键,后者获取对象的键。

    1. interface Person {
    2. name: 'jack Ma',
    3. age: 17,
    4. }
    5. type T1 = keyof Person;
    6. // 'name' | 'age'
  • 通常 keyof 会配合着 typeof 使用:

    1. interface Person {
    2. name: string,
    3. age: number
    4. }
    5. function getPersonValue(obj:Person, key: keyof typeof obj): string|number {
    6. return obj[key];
    7. }
    8. # 上面的 key 参数的类型 keyof typeof obj 值为 'name' | 'age',这样可以对 key 值进行约束,避免使用时 key 值拼写错误导致的错误。

in

  • in 操作符通常用来实现枚举类型遍历 ```javascript type Keys = ‘name’ | ‘age’; type Person = {
  1. [K in Keys]: any;

} // { name: any, age: any }

  1. <a name="d59c3d53"></a>
  2. # 装饰器(调用的关键字 @)
  3. - 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。
  4. -
  5. 1. 类装饰器
  6. ```javascript
  7. 示例:
  8. function sealed(target) {
  9. target.prototype.msg = '1810A';
  10. target.prototype.getMsg = function() {
  11. console.log(this.msg);
  12. }
  13. }
  14. @sealed
  15. class Greeter {
  16. // greeting: string;
  17. constructor(message: string) {
  18. // this.greeting = message;
  19. }
  20. // greet() {
  21. // return "Hello, " + this.greeting;
  22. // }
  23. }
  24. const g:any = new Greeter('1810A');
  25. // console.log(g);
  26. g.getMsg();
    1. 装饰器工厂 ```javascript 示例:

    // 装饰器 // 这就是装饰器工程 function sealed(msg: string) {// 这是一个装饰器工厂 return function(target) { // 这就是一个装饰器 target.prototype.msg = msg;

    target.prototype.getMsg = function() {

    1. console.log(this.msg);

    } } }

    // 类装饰器 // 调用 @getTarget

    // 当前的这个装饰器加上() 代表的是装饰器工厂 @sealed(‘1810A-你们是最棒的’) class Greeter { // greeting: string; constructor(message: string) {

    1. // this.greeting = message;

    } // greet() { // return “Hello, “ + this.greeting; // } }

    const g:any = new Greeter(‘1810A’); // console.log(g); g.getMsg(); ```

    1. 装饰器组合(多个装饰器可以同时应用到一个声明上,) ```javascript 示例:

    // 书写在同一行上 @f @g x

    // 书写在多行上 @f @g x

    同样的,在TypeScript里,当多个装饰器应用在一个声明上时会进行如下步骤的操作:

    • 由上至下依次对装饰器表达式求值。
    • 求值的结果会被当作函数,由下至上依次调用。

    function f() { console.log(“f(): evaluated”); // 1 return function (target, propertyKey: string, descriptor: PropertyDescriptor) {

    1. console.log("f(): called"); // 4

    } }

    function g() { console.log(“g(): evaluated”); // 2 return function (target, propertyKey: string, descriptor: PropertyDescriptor) {

    1. console.log("g(): called"); // 3

    } }

    class C { @f() @g() method() {} }

    输出结果 f(): evaluated g(): evaluated g(): called f(): called

    注: 会先执行装饰器工厂,依次执行完所有的装饰器工厂之后,再从最内层的装饰器进行依次执行

    ```

    1. 方法装饰器(方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。) ```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’; } } ```

    1. 访问器装饰器(访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。) ```javascript 示例:

    访问器装饰器表达式会在运行时当作函数被调用,传入下列3个参数:

      1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
      1. 成员的名字。
      1. 成员的属性描述符。

    function configurable(value: boolean) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {

    1. descriptor.configurable = value;

    }; }

class Point { private _x: number; private _y: number; constructor(x: number, y: number) { this._x = x; this._y = y; }

  1. @configurable(false)
  2. get x() { return this._x; }
  3. @configurable(false)
  4. get y() { return this._y; }

} ```

    1. 属性装饰器(属性装饰器声明在一个属性声明之前(紧靠着属性声明)。)
    1. 参数装饰器(参数装饰器声明在一个参数声明之前(紧靠着参数声明)。)