TypeScript 完全支持 ES2015 中引入的 class 关键字。

与其他 JavaScript 语言功能一样,TypeScript 添加了类型注释和其他语法,以允许您表达类和其他类型之间的关系。

类成员

这是最基本的类 - 一个空的:

class Point {}

这个类还不是很有用,所以让我们开始添加一些成员。

字段

字段声明在类上创建公共可写属性:

class Point {
  x: number;
  y: number;
}

const pt = new Point();
pt.x = 0;
pt.y = 0;

TYg02iJmECWxgfNxsBO0+/WKuo9CkiWXxd0FBBcebpa4XvdsBxpWYKsB7bsEo0+ZItyVHhbvudzyBTtLBrHd4nMPmAD4GaYpvvphUGRkV+9NezwlqbF9zCHEZl3wZdi+zQCWDqWNWbBeV4P8g9j8Ig==

5bFVeKBbRNLXL8C4oJY7bjnOuRMbUbYyFIdAmp0SPuCQAaVO2gbygcTF/bXLPx0Gx6bDZOvUR0CVqnJGOVESUkW/iws9B+kE3IW6lZHZEIg=

class Point {
  x = 0;
  y = 0;
}

const pt = new Point();
// Prints 0, 0
console.log(`${pt.x}, ${pt.y}`);

ffaMHUAL9bZDPvTtwgvIO/Klq7r3yG5eYWWe0bS6QaAWHPc4LS2uLmq9DPjOHN/o7wVztNXra3a29HHKP6YjPN4tGqT74uJbjwz+IBZWriLsjW8wQDaD3HtLc5NB56ycB9wXdxI6VRqZ47q+9eiASIQ7BNyZiE912T69o86Mm80=

class Point {
  x = 0;
  y = 0;
}

const pt = new Point();
pt.x = "0";

--strictPropertyInitialization

MKwzgaDl/2etXNEpGHtRmfP0jmnGOVrL+9EWtTV+TVX+02UcrY5psprTvQfvcXjdHrjt1L7Cl2jnx+fAA9B7bSW0B962q2fyI0HUTdhp1Oeb9M4HJQ6nhpWaJBtKrS8CfRHhcGT2K7KBVmlG/r5ZraUN4fEur6iakc8y8zMAOjqBZl6atNIzKLPIlvv+q2SSVYZTiLUqaNUGwSQaKCmxdA==

class BadGreeter {
  name: string;
}
class GoodGreeter {
  name: string;

  constructor() {
    this.name = "hello";
  }
}

48Hv08n//fvohXX3Yh0000qcdmS9ok2o1R24eTZrsJJnnfDnDo/HelKhKmyBrvdQTDrvmVZb/JTxNBi5u+YxPPgCthHihAchsj/ekWH3M1ztxDBcyl11GKMOtWTxHwcsZ+m0NWNXEnFM787UM/DJ0VLJKHkERXiPRW6ELdhhqo8ABpzntqevrxVPWUPX1LQHnVs1BtVKIlnsBBxFQRhD1aah4hOymtfLE4JzIOghMI5gWvOA4JpeQlhFwBRkJmdW6ksYHPxGWzHhFH/e/f2gVC1qquxO1/gyQHc5AJoj+v0=

pX/tkpLQiIC0b7SoF6vtF/rDDrhGaMQJTdepe/EmQNyfLYaeF3KNHf87lE321XmcisXT6Sc81qDQrdWwd8YXge3/eiFq8OWxKZtnfsrrI6jpSM6MS2JRPoASEpTrsAHLTOtWOw6hsAuoWBHKubVmFPJGKo3l08NfWlQ7pKOjMvL0LZMJiLyPL1S/unQ5/bPqzNTPNlUbzpYSOCWnVCpiloqw7zj0UkSiQMdkqecm8wmN2p5bNZHUX+5mEG+dasFNDEgAqwvLBLwugxNLBibD3e5fZ2NugeDdFObQzDxeJlg=

class OKGreeter {
  // Not initialized, but no error
  name!: string;
}

readonly

sqeqJ3YAGJIuTfzIydXcp7+aVdY12oVD4yqL31KBm4nyWkbcnqzQtPyKtMFcnAg5N7ezh/BtICcohn40bD6m7eB7iMlN66GUKZGI34wYGvn0ki+3XdPjj5CzCo239g5pIXycFdPBQMRiDNVNU6DA1ax/I6ZStG5/C9/Q58MYwGE=

class Greeter {
  readonly name: string = "world";

  constructor(otherName?: string) {
    if (otherName !== undefined) {
      this.name = otherName;
    }
  }

  err() {
    this.name = "not ok";
  }
}
const g = new Greeter();
g.name = "also not ok";

构造器

xGGb84375EFoZbRhNFURX3xPoopTasiyKjKdl8cjhaUpXZW1lqz3E2A8XiOwlDoByMkXeSoSUYwXnrU6usWQPicO7K4aR2rygZFikzvIwCwU7lhTmKOpZ2JnR3K2kTppVCnzGbbHB+3SUzP/Bxa2Hg==

class Point {
  x: number;
  y: number;

  // Normal signature with defaults
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
}
class Point {
  // Overloads
  constructor(x: number, y: string);
  constructor(s: string);
  constructor(xs: any, y?: any) {
    // TBD
  }
}

1WoFxQiV9Vk1iHsfGoVfUOtRNOvweEy1rA+JM8QMWdZMP58VoX65FGr16JFwBXSCJPJxOe+YPUhudG5YhNAWmg==

    4PCYqfiKv1kAUGnRyc3sgMLm8EVsd3kpcY88q3pYa4osmEQh1OCs8aWmw6Q9/arlf/bRxNwTQmnM0C8nBC9q9Qbh4Z7+Kl+QspZufoHocrdxr58qMS37F6lGp0Qt4az5QjZG12E6/ZigRyb7Z8jedOojbiLRNd25dIqB0t1XcVbIH1aIib6tvRMnITFqgZlnvaRt04jvUPMr0SmTQe0A7i+J4w9dAdiz+cN82uPOixT3yqSx53GUdo9Furwfh+XQ

超类调用

JIREu6cDPIIno0pcTxPAR6iYoA/YXDbC/vQOuNvkIRy7bV2IlxKonf6dasIU+EKM+jlxI561cUHcrIxN5mP/GBHMfVNGxafmGQPEdVH3Wev+iTnkB0unhCb9b97kQ9pY3zZhtqH3lHD2IBxg6KWQhBXOjdkbOZ+1ErkHzo33Bb69iHW/kQoih9HiKxxrHxtLE5mYKvPfXTJnn0jv/OotKUOyGZx9EyzE9ShABgwVCOU=

class Base {
  k = 4;
}

class Derived extends Base {
  constructor() {
    // Prints a wrong value in ES5; throws exception in ES6
    console.log(this.k);
    super();
  }
}

YP0CQwsKSpr/tVNs3pA1svInpbWBdws2MEPA1ZMV5LTuxljOKJx00IpE/5xXl2sH7X8aBX3+7Gia05TgAGt+pQ83yoJ8kN1BMODFrqbvuMZ+HF8sOrhPzB6TYk3cGZ6bgUmqF00AMRKxJsw0CrnubJwgi5jM3mLvqhpC2/hzXOY=

方法

HPnGEYyh+loFqkx7j+9u+y+L317cos7Luiu1hAB3iMjwugS68VLWkoMGJQHuAd2650j/KfaFU2A3YAbUG8wNhvktop4/DmrZ5eA599VRepvjwB7hfLEc5+wpC+5VQglxmz4Gmjd4LzUEBKccoXGa9g==

class Point {
  x = 10;
  y = 10;

  scale(n: number): void {
    this.x *= n;
    this.y *= n;
  }
}

J/0yZrs8J0yrLXp4aY7OjIeN4i9SaP6Efq4XK1VygcBenwrcWg6kUm++WGrls4NYDw4gdvjenn6ZY2CWO19ZLCYN+6XO8vfiyx864Gu+hJErlNaxT80byI1QzncHC0/6

UD/GebFdoMofh24ds6+9g+yYoSwny3ZkJiyutZKWrwyrtDfgEM37PCR2XHhp+DXddoCR9/Ac3Q6z4TDLMZOL804ScGgd7sqHmmI5qfvbsTiCVtiR5gvmvK/s/tLIz5QAvYe4a79T7f7eLyhVLMqyB8z4OxJOTAbH0zb9p/4ko5/ftW1zj5yVFQYVoEeJobA0U/UrnYE4/qtZNbaH8QLlkhPPKrT5LSi6g1bkYg+pCnqmL6ncNNJoGbEVVinHRDHv

let x: number = 0;

class C {
  x: string = "hello";

  m() {
    // This is trying to modify 'x' from line 1, not the class property
    x = "world";
  }
}

获取器/设置器

FEd08a52G9w9Eh7uoZrdXLAOg6NYV4BKjFNr5kntAiE=

class C {
  _length = 0;
  get length() {
    return this._length;
  }
  set length(value) {
    this._length = value;
  }
}

MaDdStm2M2gOfJ65TX3XTPVFdK7EpTGXw3aV1E3zdRpEl4Wbe8XlPg0CQ8OPHJVRsHrqB69mMOxs/OwpEkolnB355cdE6+IA+5YU9N0ZxORPguIal8IZ8KTgHITAuESahIfKrzjQdPokeanIvI/0OzrTTf0vi43wDwPY+OzpgUYYFzlvRnorwIH/bnr5errV5bdLo/NrcDCO8rxAFlvvhyxusXv/JeYUPY1a1QHDVd2eU2KUuERdkCSi1dMZRWVt

L279v8u3tnZokZCuKg4MwLPpmMZq5LslTsPakbZNSQ+OQBfaDspVoYWa29KVuNNyc8dEZO9D7bDRUFCBsyJnRA==

    ugM3qD77020wFUZMosk+MbJOVApNqtQcKrkvyf+b+FUgHHhR44WA7rCr7JpdY0jO0TbiZ2U+q7sihFhKXxhwDIX+mtUOuDnhzLRp/kkf1QkLdxU2arqfHlZqW07gCKoFgJI5YwlwYteOqSCpsmZ/1VpV7tZi1jqrfYCbD3oGf3ARRdj809Qxd/iNgLNOe3kPw3IZMRUH8Xxxe/6o/DheWiIQQrcxiGSVD84fXzc0vQUH4wu6z1cvfJZnFCYbnKFNy3PVeMvwK+xUCgpNeGR5uZZy7FVEo5Ndst2+AVBr4z5cn6INA3pHltYHljIStXCNU8zwmZ54goVFxWxLvOVcHBwatuNchAFLbej9xsGzohWpHWMx17IbW5Gazyw0e3PDTYO32ryII5yOyO908aSvhw==

4LB0CsLcdn8zsuy7JcLkg15iS06jOI9mf0gQwHh/Iwvjen2d/RsqO6WAKqZbzS4Ndv2lk19tSAkhyaEujoy//4ZOe9uTPq9E9z5rI5X0dda28yEk9BzDBi76rKpPT9JDiP6OjxyTXlIIQ2nHOxswM4/1iuZJgV3RKUN4aRYskQqJqnk+I3nYtr1voQX6yvaj

class Thing {
  _size = 0;

  get size(): number {
    return this._size;
  }

  set size(value: string | number | boolean) {
    let num = Number(value);

    // Don't allow NaN, Infinity, etc

    if (!Number.isFinite(num)) {
      this._size = 0;
      return;
    }

    this._size = num;
  }
}

索引签名

4tZrD6+hbVAy3Goq7hvUPsXR1lBWc2P6rqp6gpiuJ2PXwEpYAQ/ivaWiGIBqc9hwBF9DWplqV1jM9ea9j9hr3DD1BLRPtrKDxuXHi5SgSFVcqxQ1CzHitEZaGm8vglj15FMkPwZLi4QK9doc9hz673YyAXKiLXFpN6tYbe0O1x8ZTz0stlLTqYdS3sb6Ptvt

class MyClass {
  [s: string]: boolean | ((s: string) => boolean);

  check(s: string) {
    return this[s] as boolean;
  }
}

oAHHqswxgNOgD0f+8eNlBK9Ei2wijZc2R4Rdu/bZYSqg7mgdFSNSoZlF63CgnHmGK+r/sM5UThRm3kLir/+ir9JJSAWSeSDlcC9z6mZBiPmeI7WJMoK8b5P1xTvu5wzqNtD+pmeqrM5ywk2SIUlA0oV2ic3Bh5mBQ/Bd6lt6Roo1b2cjXRtdkKVI5NsE/5IrZQrrY9i275sL5y0w6JJFeN5EVICyp+lI5m8zpmPCg2ev/4HqTv/F3xYESGSDlZ1Z

类继承

3O1nSa+ZH26miZqVav2v4koAKmSDvSDn5ffB1EO76Piyt7wpBflyWaEF+bHe8QFN8WUQPrsQw3rVq2/Q8EGSJ0H/rm2QukR7p7EjkyawRQx5BmPJ9eegVYrMnl/csOP7

implements 从句

J8oSYfJYKkMEwEIUlwpJRgqu5wVMe1Q5ejaZt5ksWxxrux7v/T77JBXduc76FazW0H50SL8W19yGfEA4RYpZBa8YZtLIi6T88zMBEolnVeGsZuxTD3jSobu5NO5XsSrc0foRkZhSwqBENTKtje7+mgQEug/+xxN2lZMfol/5C/BeomS0c2QsoHyg2uHVw5AUwAu2krlKsnZGlZDeWOhXrEQqTIWxFjnHL65jSvDMf58=

interface Pingable {
  ping(): void;
}

class Sonar implements Pingable {
  ping() {
    console.log("ping!");
  }
}

class Ball implements Pingable {
  pong() {
    console.log("pong!");
  }
}

aANP+E6YUSfsZIurlPKeJ3jIUjCG+kswHvNyO3A+CijyOywJBH5Mx3hCXWRzFDnLUeCQhj8VqE85q66rlR+lA4M5beY+cOFzEfEGCKMmODrtFF/mRBcrDnU+29bbrrIp

注意事项

I+dhTgJl2UxW+KxGbdi5f1N3UFPraEBcSeBjAwZ7KBMrD3mYK3M9syTWUloX2p4W7bJzwa70c7mWZViP711/fX8kVX89PaRfyth6MKh3JQLs5Smxc37+2MrlYLALIDMueSfits2vQJtl4BF6psCMVmwSfj0aNVDQZRRPFL0oxD7YKn4pzRq3vbcMy/Ca/58FSvsNRYUFv929Msxf1UrtChDxzRvUMz5F4mzmDIRT1Ujajrlf3iRgOrTt9W9GgkK5v3sfy3wOCe3+TSMI4GrA3spPRqiUMBqlRA1DCgIZd0s2EzX2KAXD1GUHteDlB5SnVjwXKMzoZE+JNhfococJpQ==

interface Checkable {
  check(name: string): boolean;
}

class NameChecker implements Checkable {
  check(s) {
    // Notice no error here
    return s.toLowercse() === "ok";
    //         ^?
  }
}

DqskTBOIqZ9mPv20fgK9zM1OIw02cLkaNGtYsYQXgXQrh5bK+/GiwP59IyYV+a1BVjlGQOP87bYbc/WcADAz4R2KvweR04z7OCW53aCM5AL3YOeFVVaGosqgX9JG9aFG0X9OkjePgTHAReFGVSaeN9SCJDFDbsnqmECJ3DusdlYgSuU6OmGzJJJOoGyQCQk5HRwgnNhMOlW9X3iT6HmPpKZvEwAp6Y0t9L0L+PfFl9+lits9JpG6BW3m9S/RLEDjGdK9/Swcy5CR75aPeU8MgUfGlpP6pREvnwlrfz8ycVzlbD+qWm+PlPJmIEibLGH1Qz+BNHBPxLb8RRCvmWV6Zg==

3LRdRCQc9l2cCp0VGgbKN60VQmj8TgNs9jUBKLbBTuA3NcCX7V8u3idiPJhActpLG4mD13QUC5rbfq9v+ZJ8eg==

interface A {
  x: number;
  y?: number;
}
class C implements A {
  x = 0;
}
const c = new C();
c.y = 10;

extends 从句

1zM8rRZfMJGcJJTat4tfIhVBwVVETgjO1AXqHPu/9nYHxbgwRlm69rByQfLYi5w+pMrvaPlP95+Ka8Agqq3osFHP8v0lOflvL0X+iXa7pJnfwD0kXJq137yVrzRyBw4WbmZgdQtLS7V6fWbISiOOWA==

class Animal {
  move() {
    console.log("Moving along!");
  }
}

class Dog extends Animal {
  woof(times: number) {
    for (let i = 0; i < times; i++) {
      console.log("woof!");
    }
  }
}

const d = new Dog();
// Base class method
d.move();
// Derived class method
d.woof(3);

覆盖方法

+3cbbNhKaDyd08PPuMVmWLTCvAK08e9jrJ3HeHrwSpt03KmQp4GZPUb6P6bU12ebZVp7hMJskypf5rjZOmYllWl8yy4kn6PeAPBpSzbnYpLkAUVRyvceA0Iaa76CFRjv//mREfYMe/hAuGkpBV1GvDai5xkZb/9HDLzxcAqPoWuFcZJzxeLq3DG46BhM1NyexWs4G5I58V/0JtB+38nKcgL/tUqJOFipQplHt4L/Y1jCrXgSiXjMD+AVGszciJ5OMaHcvT2LR3aXt1oNTTXWezdcEqxl1P07EZjW6sucilI=

pY0SOMW5H1ZEyDwRrUIW83X4ELrWRh9/lg1IFJ2bBn3zg97cdBFBj8n153ivXN2bbhwIg0y0FMdpIjAcUCpgYQ==

0iF6TZfVlq5Vy/JK83y2rSE3A1xCnBbF2jhxk7aI19yg+ox2cSfpuYPsvhqdeKc4

class Base {
  greet() {
    console.log("Hello, world!");
  }
}

class Derived extends Base {
  greet(name?: string) {
    if (name === undefined) {
      super.greet();
    } else {
      console.log(`Hello, ${name.toUpperCase()}`);
    }
  }
}

const d = new Derived();
d.greet();
d.greet("reader");

CcBItEJNGlSOjlj6RWMswxcEsBXSZqqbs7EnGuaYu+A5AqCGAdB66o/4UOo+fWsm+VfefkJZ9Felxu6Iv5crwVXn1YExnCaBTvUA0d1JPpGDIHayEDu7glrmGvXZVu8yNxsjRK670ui3EgTD69hnBXO4rPDNj5goYhm3fyo7sMm77vb+crjcLeoe35HhKm+hMHMlSRbfz9meya8kQoiIMw==

class Base {
  greet() {
    console.log("Hello, world!");
  }
}
declare const d: Base;

// Alias the derived instance through a base class reference
const b: Base = d;
// No problem
b.greet();

i1+qJZA5zu0tt+5R1DTRTePiTLhrVKwq/u/HS7Kn8tUtjFQWdzmSNHcpv1NtApD2p22NXuH0eL/EG1xCqvg0KkgWTzMsp5JEVR4FrYSRW28=

class Base {
  greet() {
    console.log("Hello, world!");
  }
}

class Derived extends Base {
  // Make this parameter required
  greet(name: string) {
    console.log(`Hello, ${name.toUpperCase()}`);
  }
}

nDhNvVtmqUJfaMbfX/JTr0LL3g4CvHDX+ZISPqmttkl9/L4SQPOtIiQv+dM6Abt3xGh/kSczRCYuersc52knkVFyhhx4omO6ipPfkVEVPHSXM1PqmtEzglkkDmoUQz44

declare class Base {
  greet(): void;
}
declare class Derived extends Base {}

const b: Base = new Derived();
// Crashes because "name" will be undefined
b.greet();

仅类型字段声明

vRZILExryAh0FvAMwBQUOuAAsULQzS7JLv99mee/DRd/xHJQafz8ivNxMcVHBSzLVMB5v1iHg+a8b4vEDeRC6ogO8yLc6xYUX7AlWqmyIy6JCywjEhccBD6NlW+aM+W46VwcFeP/yyuJTxUazEOyheW/UpDo6eBKmpgMiQVYa7DTlWj0SkBeRWTWc0SHoyfLEfARaqsl9K4uv8jUOlP7T0K+wfDqlspbO1IffBubCqIIrItY8VANApuI/UNHg9X/T8yJ7MNFvrSCaK2Gc2nb5p+g8nGzDvk+mBFLxwp8AmsWswWHs7vhxFDXVutz+REhMdV1l2DUAxKHPVFW3QWy3pj7eZMrMQtmokjA5aZTzs8UZwuaNnPUM9Nl8Txi3KQnk9GDz6N2t7tfixghjhHrjSFRffY2J/6pGnU/hGRRY42SsGSk7TgHThmnAj8wEF40E76/WCRi8C29/+G/ulkYb2rS9a0zCk/Y6+v2bBbKwwQrWEfI8SyV1tB/3XKvDg9fJSRgywQGV705XTTY8+CbyRXgKYbyDE9PUtX9JMUsjvqwpm+G5opRT0cyH8Ndocv/r7J8wbMG5NFKJYdxUUD5Veo5YSzMi70PgGyPix74+PMA7Q1pe1S5FM1ikWA3BEQC

interface Animal {
  dateOfBirth: any;
}

interface Dog extends Animal {
  breed: any;
}

class AnimalHouse {
  resident: Animal;
  constructor(animal: Animal) {
    this.resident = animal;
  }
}

class DogHouse extends AnimalHouse {
  // Does not emit JavaScript code,
  // only ensures the types are correct
  declare resident: Dog;
  constructor(dog: Dog) {
    super(dog);
  }
}

初始化顺序

6COQi3HNarwUaNYkL90lqi8vWm7QslAV2LMZ7jDBJsk7JZS9ozV/ftbcWbiDuM8uEG54rEUWPkavqt/KAndoLNI1bYARRKf7E/zHjNbT6jTQyAj5UrEbHBoILhQl7dGyhACW2cuCrtkhjG7z97kH8w==

class Base {
  name = "base";
  constructor() {
    console.log("My name is " + this.name);
  }
}

class Derived extends Base {
  name = "derived";
}

// Prints "base", not "derived"
const d = new Derived();

AftSAa7e0/FV9Wp8r0O78MSpQhpKX/P9I3hjK1pAaBE=

sKvY8DvzQ9XcYa/bpv6hSzruxqmyYg/JIE+sYMSvvfEJfhJskNIcKFp+de4XPdIu

    5hDCQ++hAsPRe7VBfGtCAAAIsTRGzauLFiDFamjkOPJJR1+ZMSvjleh0eg5R2zhibByTN8UFzaXw3lHHwu6jYOgdkykIUZs/eOg/qyibFh3jB5OoUliaYOeDaNGc1yzU0ZSOtc2xKObg/b+N7kG9Kf5cnqqctlSJKtQPr2ghDXnXMxTuGuLx+anV1p/qYdW7

lXH/cIfUYGLf+ljscC4GbV6MHXYFtBDaIyakGnrAcvatODlPYX7chGuzAVh0hTHrVkGl2JcceOGtMGy7MNCMOhkCPO0WmvZC93n9xqTQtkzk6sBwvf8xIiyQPMIDjXIcTeDlJwCMcOEzKezbvYfwAFtmCzEvrA/8RXanIUDwvKQGhPN5C0WO7KmAkbUfti2JoB6reZtUTEjCRci93DIiZg==

继承内置类型

qBnTO/yzSY/B0YRgrSqlAtMexrUZMNvJfZ1niC9Y/z5nygOFjBoW+VZwUxaFXCZ6b1gwQqJ6bSQD2/rWyG4jdi2DU2k66ghviNEN2figY0z1olHheYWGrMrHkK7RzoVr2C3A/PSQHm22LjUBeDfZE24SvNyqU13Gg3Qeperc0zPxX3tR9sYcxe0hUYKaqYo1GTcJoaLWazn1IZ7HfB3OR6o3IfNYx1G5qnL0kOuUu5yXEOkEMoq2rjbaF9IfS4H++v4MXXVR8dpYp9wUVg7LOb9LhRoEPLj0FzRqZd4RdFDuJHfS+ZG9MzsyozZcbpz3

sFbV3L2p7kRaY6fjlUuhPyd0o0zAz3NdFOTG10zTvw4+GZM/4qY2w3Lg2sTjBXe6aoUgm2gsu+zT3bwALD1ClIGHjSoNM7uf2AU0pAVOLICjfPejhydheIMrKbWGCBbUw5OFUGozWaEHF0sfybKDiro5lgR+c9dSy9F7J8p9ArbbxCbv47cnJ0XSu/4YCpvfvY6XThYaZpBJK22OOLhzPNqS8g0yd7x93wRNZJEBWUkuRocr3CeSQRxuubYAgzjMWQFXxQj4tzT6TmH3/3znZjXDFycbbTnm+ewDXZqm+JM6933XGeteJFTtPAb9vs1U6Ymg9JkB/76lB0VG4RDLXy3VmwrifRwkCDzs/RSishI=

A4lzkQ9yhzX3crmTRHh140r6flpAX7EyoeKya40Xkp016/wOL5c3S/AoCXnfllYZbnBLQE7y8l/ri/3l68cT2NJ4OHXZAXJe3MyHgw4zbEXjJ7+rqBGi1LC+DlNAx9hTbxstnTGrC8a5Ai5g+NAgkHG+i5WFCGeVsI1BDyZHVdz2YHWa24+sQ62HKZsPN8qycX5jD7AbLIjHsBo+Llm3LC0eRetjNiM4CgG6mfwCKuTQgr4SNzhu4F+uiUF10dg2huZVSFn3HvqElKKaDLwU2llvd1qlF+M3tZPc7a/pgsLLZ1fbI5kEWPmA61RQBe+3eaZ7/dHbp+iwjlnBSPmPXur3tBSxBEZdgdlgn03qaQc8sp0Kbp3e1GZp/J790x3TUX9UEJC///wOiBE6FZt/BlHUo7OZy2eqOmGgGRD2S/6KxchIBKO38X2vGt135FogbZspkxR20Ma5UgVCvWiwTX8fng76HNh5wYeXZUxko8FMKVar4q6hizwUkm6SNgyJLd6dsLA41ymY8pyPGcPlNzf7Jf2GkStMrKYgtm8lzpA=

wQc/HeQDmYrxdaUfpoidBinqKvj3Py8fjykj1Vs48Ts=

class MsgError extends Error {
  constructor(m: string) {
    super(m);
  }
  sayHello() {
    return "hello " + this.message;
  }
}

Ks70j3eQZU8cQuUgCg32sjTqXV3bAF+n9F1URA89YvM=

    qa/cBkLp+RBSQPFAcCwwcuEYvHXwMc0GWD6DnrqR6R/UGjXXEmBCi6ORTqoCLw2ScXySyaGpko6STVeRxZlEpPwGQsawWXL4JX03SwPZqd5zsiVCEMbZhz6fJoIgDS5/ZW8jDnXb/zlWFpbAvkanitP5n8TrGVRpTsFrnBh6YQ4+/eEdP/cgmRDZDjB86t3WYcGEe3DZq15aJEuKeVdfQqQiRvBMByNNQbwAuo2c5ibSMudvbaLNxS+z7/qibjidBGD8UlyerZcfGNJsXPcSgaU4BSPCoOHwHnYvaBpsvxfqPfJl4BfRVeK0ZHUY8h72DeHt4B8hkCXtsJmeOjjMS+RDgPRRoBEsaadWJKZyYEJb1y2eczjaAf6OeXefcpYz0N0W57aXVrsxtaAOKVCxpmghSU/YxEeOQL9QaVbCD8o=

CmlE5u7k3hX8Ek7mpLx4cFwrvCTuWt9OU6h8k8n0TrqYSBL342duyN7CnnM/FYhnyKsWXdS0196XD66n8zUesdc572kdXsQRkdnaaRSEuSJ7MsBrO6WQbBjpOfV2gJ/v

class MsgError extends Error {
  constructor(m: string) {
    super(m);

    // Set the prototype explicitly.
    Object.setPrototypeOf(this, MsgError.prototype);
  }

  sayHello() {
    return "hello " + this.message;
  }
}

QPEx92pLqs4iethYETYGdxucL+cBssH8iuNFVY+7PXF48+shhRGXjA5s6CUBYSchxi1oiOgShAKXKrjnUwr2kHsZ6ymC219pK4gNg4PiXBL+OnsqC3P3gb1XJghL0vqov3WRz9k3zFw7Ke5iFk7kqhtbvJt5IRazNy/9bVW4qw54ZtuOZ1gN/87jS9iv7IUJ5zEe7/pqnC9Mxw4TZLSXesiIpbDN2fM4inDTQaG6abz4enPeJP5cd8YNFk6V2PRpx53isqaVnjqqK9WJcLR098LiXdZ+IzPYf2tIyCDmLETED4M5ykQFCgSjyWCmsrYtiB+mzRfbZSyXygTrAIvvHnm/ZleFvHRE6vT2KtFq2NRNS0j1A2Dbc0dTzGl/XQRPa6OyTk/T35Ti5FzBR7wZTA==

qsJEj+Ro45A5iiC9J1646NdwiDAyhpyPGCE24PAkLEwp8g4D/6nZdZ4/aLvlhKEm/btLTti+1VqIEc/bFrPSrByBug2g4vrbzOnR/g2Q2859hPWk87hxqAYT1hhKQ0QxkEkdhU4FWpqi4OE1zUsqRsumgRvuSr4HkGAZbUTX49wc9vSvKMipqeiS9uIE950YO3H48Z+6wZBvXSsVGU08ifbI9MDg9vBfzOZMqqCcKm26x+0J66nD2xm3AWGzqvMXhLSJ4o0b2atHVZxff6Rt8xV/6OLLX3cdiibj7rE/LT1tUE2r4DQh3X9scPRUQ+sT5iKSqoFaJecZJ/5WKjpA5a6IGxxR/DBp0H6SYIPdtjSfknxTIMEYZ1O7vo06tJVIBGcNh1S9Vt5BaSyqhxGvAb8yMBpWppwDoPeQ1cIN/8w=

成员可见性

J8oSYfJYKkMEwEIUlwpJRhTdzunrwfC5ZjxdBpkF6JJeEL3qWkTL1B/vLFH83j3mkJEWQR/H2NlNnsNe70UvZTspOp4ezTpdpYJKYnWlmB9Tje86QKLpPejaqO5YRdWH

public

Qd8WMkrjHd2QSlzsPRtyhclq1Qz1SaehCu1GR7dq0h1HnGRTY2Dkc9dC8/vmehOsm2FnQHuxIIrimjfai8dFEAA9LmXon+s5WWMOOVHb+I+IiktbWhtENnTINh9+reSqk9IsDerqjmqkBvr9ekZZ4w==

class Greeter {
  public greet() {
    console.log("hi!");
  }
}
const g = new Greeter();
g.greet();

F3nhaZcJk+ee3he5yU6NRIdOattrJaUiySz2biKBzRdXKypKEdeWQxTa6+DDnQZ7xxWs1HCXaRlSbnOidpoX8m3Jd0fa7O4xFBExqG3lLcD2A96Ly0JZAn+A31LyGShxJyxso59HCsp/taoDpGBvQPGOUU6rcqtF/E3O2o9dBOq1KciXKBuJdeInMSAJATdf4TKhQLVSdfppon7bfoNX/e2LIbERGlTeeRiLtA+iV4Q=

protected

1MJYYkRcY+mS84FU9gYuthnrwUrkhOKXsMhbYREPkwaYRHGzq3DmhPSqookqw0/1y9QZBr5JdxlEmwvA02pkfX7SITgw+Xno3SrO2G/LZck=

class Greeter {
  public greet() {
    console.log("Hello, " + this.getName());
  }
  protected getName() {
    return "hi";
  }
}

class SpecialGreeter extends Greeter {
  public howdy() {
    // OK to access protected member here
    console.log("Howdy, " + this.getName());
    //                          ^^^^^^^^^^^^^^
  }
}
const g = new SpecialGreeter();
g.greet(); // OK
g.getName();

导出 protected 成员

BP4QSyNcIvKF69OX+EvOloFBUrvOr/iaxSK1aHw5zTfGbu6Hssb7/N0om8nEWexdnhS+N3i/bPNJ1hEzkMY0nataEQ2weZ/XEBzyfsVhKq1euyFxIw1AuPxS7OKhLkG/Xub7ehL/T2FFlydEIzsXd47QQFFNorGDhZZuSdKU6c5ZPbskScJCMjnJfoiJY2naQon1wReibAzelJbA70O6V6DMJ5nu37lbITb23/F+gw4=

class Base {
  protected m = 10;
}
class Derived extends Base {
  // No modifier, so default is 'public'
  m = 15;
}
const d = new Derived();
console.log(d.m); // OK

HX98z65sMkJQvrxufuEYVMF9l+4o2/mgSDmrOtXAakwhulKdcnySrJQjfD5Usa7zaQ/B1KK9GCqtRGE13AF85APwax1eD1TOJ/sQoPpZ6VWxiZR3LnBdTU/ErgUz3te3EW3THfvsXmAR8Iklzw7wQlrWo9wnJCVHrfS7jngPUVJcScMQB1JWmVfJUCBKUvK79VK2fr0a56L3tAvH/EwTIaDPrAXen8yvQgBT8oYC6zijwzAjQijwJp4pB4ws//0mnPUmpFePJwfjR7G+6cdiOIfpRdlBCuiUgXOjqk3UZUJWtXfDoaU8odHTR6tJ8ZHcSAosltYDWlMV+fZhiBGA80yokgdfEUy3kT2lV/pK9uG17b+Gt/D8CHS3piknZbDv15r22WWiyoyCj2I2qKVeiw==

跨层级 protected 访问

XuNoiYvLwlZtkKu4BRlWtB26/tPxhCXe7HnUCuhb6BrU17xIGszbdmWEh7qjWDOBeS5vo3+F39mfkZTjH/PvOPxcpH3pixnEwxy78T9F2wemEsDrnQSs8dd1hkol8SIJO6jcvcaBCKF2YHqLckEmxA==

class Base {
  protected x: number = 1;
}
class Derived1 extends Base {
  protected x: number = 5;
}
class Derived2 extends Base {
  f1(other: Derived2) {
    other.x = 10;
  }
  f2(other: Base) {
    other.x = 10;
  }
}

f/KNxOM5K6i2yj/A3ab3A+iAqJnWD/9HUKIrfLt7ZPEX+BseGXCqGNmv+ZyaT9LI5Y9ZoO10TcsPKiu6CzT8DVvnowlzACjT22DwfNgYW+lhfBBm96JodFiUKyGHZR2PfJbia5jFk5124EKIfRZA0Q==

PizIQz3Qf3RV12YQq2Tg39bGZADFbFLp2lNOIa7c0pWH1yvYDDGzq9yxuranwrgUgaVXtSFFtcmY+TfzFLyN1Qq49JYVg3d1zcyeqncAS5W//JHN2gf+izszR0n3eJeWScx/mnSA8zrPHJmK4rLTpi8QglbwJ1Apz9ik1GjXPaGxNWw4y5xUIGKuP3oFKL/Raug2He/QEqGPqCMCLfmGAcdQDcO4ayjx9OTA7RxM//cIrzD3IIIQ+vMeIxyHwZkthDkAgH0CgkqMf8i7mO8HCfwPxTl6MaL8Z4zSBGadyMYHvjbJHkSEIEgF7slHmAaZnY4Quo5kGjp4QH7H9ovT2HmJ9DOMWAAU2PwUJa26Jec5XZPNzhwTLFaGrNtoAqID6N/sWtZ2O2UW72atr6iRXndBX4vOREjfxSM+88JHR+C5RUiJEyQHwJPR8/sGMiVI0fM1zdEjKEqOh3pIM06Efjg/QQ0kP2u/TCV9MTbI99neZT1nDIMAbK+8uSjdOcraQjascsqogJ4WgZsto/uY2g==

z5vL6UC6n1k6F8H/lnHMXsdTAhi4VRmm1MPvhD6pYdluSXoL8I0fEIVrSRHgJDM5sNljG3EA8WW+93GairxNtyLulcyHvoXItSKzfG06jRtOYyqQfh2ZtjQV4PIWaQa63qODuHKoMjK51K5G/OQ6FYRinR6BEvlantuzKri2DwETOpNF/huLrLRgkEAdGFN1R2hb/cfoyYsWGnsTJzygBA==

private

Kxyja80vIl1lAM7CqKf4vSHuLsVQrd0BYeh4rv7rJjkyCx1yvmqIcLpiTz9RCaFIwv5l+pyWOhu0eCV3dyv3shBP5lN3bUB8wd8e5xlT3WrG1VxHYe6Ax9KGnoRrVAkk

class Base {
  private x = 0;
}
const b = new Base();
// Can't access from outside the class
console.log(b.x);
class Base {
  private x = 0;
}

class Derived extends Base {
  showX() {
    // Can't access in subclasses
    console.log(this.x);
  }
}

6LENXO+V0RrvWB2p3Qr9IIwP7T0puDnaU+LRYu2PWqyMeAhT0YhoIaGBWe7WFoGxAXPro0zj0s2qiwgwALUHdxh/lTsIQkADZ2TqZW0RpV41/klfhuGR0S0GxoZ1V4ncZcSqnCv1cukk1xovsAHO+g==

class Base {
  private x = 0;
}
class Derived extends Base {
  x = 1;
}

跨实例 private 访问

XuNoiYvLwlZtkKu4BRlWtBKsl1HljB4Y7HKHjwtQeb2+Yjxl8OBUk38Iuwl504YloZzdSu5UHEOYaDBIMR8m2dBe2S8dViaCL9S2nyUYBuR8DUHsif0HBpKgk5ct/RUkD5DL2YmViABlB7+w5att30RSXTmrVJoARuNcqKOq93zeXcj1tuBUXWsNTV37vx6HBxWWtOTYBkFiNNuIfhODz8PeLMYIVldf6PPVFY2qjYefGguJIeyDCijNX5EfWyZgtH7zB/BPuBbxygdE/aVtGqDiAkisS8RdWmtxJwgn9VE=

gP4ckPThtqgd2lvG34wgFICvmXuDAjVWEa2YO3iqrD2ZJ/iGBCaVnwUWPfi41+M5rT/d99HgVo4h0elnkQiwtA==

class A {
  private x = 10;

  public sameAs(other: A) {
    // No error
    return other.x === this.x;
  }
}

警告

MoHkW3Z545497hSTTSdaP1r2WURYJ5x55XwQwDC4V1CFeUfWNrL3mKnflL1o5tJOKyZwdrVWSz+FWHvzt0K4T2CJ7xvKRICyBdSzlKl5EBjUQqIcxzpLnQck6lG5x/Kh6ru2iRpZr/om0E4EgL2iQB+Yx5OImiTCFgY357yy/IT3P7BQSfZME6850Canc1cigl13SrAfaBK+Sge6BaUS2Aq0GN+ZYlS7iSCIvaAqxb5jo+GpX+SZjNv1nGCrgUvW

MIe69COPWijxV01uhbqf2nCh8NdDQsK+yHb0iu50lIexrq6HZ9QgYo5A9Ml3rnqfetwaidjwRiAefiWYDSLtciNQZjWVa6GVTZq1Awpm0iuI2uVLL0u68uNWm0nsI8jhDasJPLO9hbCZvf1ouv9UEyeLk9HfAbwkWirc6Hf6ew5sYp3DabpbD2TyP3HpEsjtitBuQ6347i7zPyDnY1bz0PnmJFTytYB5Z/I5IOxj5lI=

class MySafe {
  private secretKey = 12345;
}
// In a JavaScript file...
const s = new MySafe();
// Will print 12345
console.log(s.secretKey);

Kxyja80vIl1lAM7CqKf4vT1ijnKSJQeAU2BFv+leN0nmpwSAidLWfwT9Rt5r/R+ssNTYt6lO5AH93K5+92a77bh++QyP9M27DbGMTg0ugpVINnjdouL0MaY+0kmZq5uIJcXVEfrIFlrsKP7lPYB6uAILIyZSa0A2+aoRlnb5LZVOyQX3WWnwb5AtN9MCv2F9vkeLE3n2V7J69Am9lJvib0OpUrZ91bymEmrRJUwB39K3a/6lncLdYGggXOrK7qAHXaBHGXG68lBQzOuMzA8nFJbS4yowwlBUKhHbHe5EHSir8VDIet/NUJ5tFYq8E+spgG6H+uCq1NYb3ZSsJjFQLQ==

class MySafe {
  private secretKey = 12345;
}

const s = new MySafe();

// Not allowed during type checking
console.log(s.secretKey);

// OK
console.log(s["secretKey"]);

BzkG9E8URxhX0OIfv0IkrAz16TxHfDR9W4Ge2hlUGVlMuEaW7XrZtXIBBbgLqu/GbVfglQ/05M6SfGlq9mu1OGfpQejCA1B6vy8z62heCNVTGbS2KcffnazZZImwk/bvMUcrXXj/y8tnGZ36IJtyOQ6De7WenVKu/8kzuxVTTYoPPipODNQh9enwDice0vwXwLCCW4D5e6JOJVR4kkuopbenJimciWgL9OH6cJV6EXPldbmw7klBNPBTFViAB61IEy80g8TYjEpwUwccrOBTT6v2uiagQNYU3tMuB1hfLEpNlHIzrgmb6Aj8vvIdreG8PTHA90uOCQaSzdd8B4EF/dDSxGElfCUYC5vn12w6qzOnOW8l4BTTvnpoPFzL9ZLg

class Dog {
  #barkAmount = 0;
  personality = "happy";

  constructor() {}
}
class Dog {
  #barkAmount = 0;
  personality = "happy";

  constructor() {}
}

AI4ebKmy04fJl+pJQtwhoYrTR9n2XSxNa5Z3zbbprcVzrfC7dCzFq62P8lPSrd35Kz6l2WdMl1L0CGbZXC7dCobzcUmPG6/4KPHwuxVWi5bIw52gtTZd/Q7Q97wXIL8Xq575UIF931buHw1xgMkpdg==

class Dog {
  #barkAmount = 0;
  personality = "happy";

  constructor() {}
}

64TtgnA9kYpnC/VRvo21PhRPtsx171Q62GyvZ2hX7hlgRfhuCN8akeS0SfhAz7FcDzSPd8abNq6jU0Cn3I/gsqx5U6S21vFxCSrqSK06JpeYa1omQcbuUZgcKTxPrtGmTkDYE9cvnyuIXUEFGZi5D2NWHYC34IZskdvGAiYHdxCvPq+/Cr+poUnOJhbmeqNLWtrKo2lQ1BeHmGKkHmTIhk5MXMN8qhpvf7/OfN3mGY+AuyYZ2JNmv+Nf+gDyGoPD/ukQ2EXSky8RpB17f2Mk8gF0Foo3A7VG5gi+mtSMWwOsgG3Z0JIAieWpFC2wetiB

静态成员

wj9r3eADP7L63ZreVUeQf6vGWLA3MlDcxr6kv3X6HZF+hPImcGsSW7yP3gM77IbwlssSgKEXCe4VnT/ncjHdRPbwcnzS441by0tOZrHFpaYkwq3tbU1zF7SGZspCZOSBWjcZ2y/dZkLzmVsLraLQq9+7zPUNgClYqI6Aey7/hihckdWxzB/x9HSUzCpfXvzuEY8WZaH1UEno7jOhLXLjyQ==

class MyClass {
  static x = 0;
  static printX() {
    console.log(MyClass.x);
  }
}
console.log(MyClass.x);
MyClass.printX();

h2Uxvam8AOxzHd3CCNKWNip8WGbw4ejPamxqBi9VN5A+dzGg7ddj7fZEpRJzRkME1ZWDHPeiz0LI9wUxE+LjRizF/OBRoUyxusYngFvW8ALljRgILuMbdDbnlCrXMKykiehbsH0HAKiaJAJ79x0wWA8aMgKL2+jrCXKtPuq88CKTL/RxGpo8TaR2S58URLw3

class MyClass {
  private static x = 0;
}
console.log(MyClass.x);

btM/Y52VWO4KsP5zIUJKW75ngyhTVO6utFwW7T12/os=

class Base {
  static getGreeting() {
    return "Hello world";
  }
}
class Derived extends Base {
  myGreeting = Derived.getGreeting();
}

特殊静态名称

Rd8imiXXp7fU1o22gMiEp4OWgW0ST+GZozKaisYmV3/TQ7jEEBEXgCRiKlaKipWiNI9uzgKI7KJIHOsPGb3Golv1ajnY0mcbR4dd9wTcPEIckMcWFqx9hymduIpDfk416Ik8Yuy4uqjhI2zQRZXy9xdMUdN7Xq6nXBppjOiKB10YiAAdP+G8BWAYYj7ekIfpxPIyMdGzfKbhMhZVgG3EuLP8v6AkddClVqu+olmZiC2fqVrmRONDH7ehE765TTN3+sjqmPaRoOTvEMVrumGR9l/98TkzxNQkCttN/+ISBVNj0Rv2+7CXzAZcrt7U4DuMQyeMsd/5cZKT679Gn4/OxYP92RvKyJ8tqDDrIfmdQZLJdwg9/W5EOrLas5HWnQQWmyAzH7Udwf305nKnOHfH3Wi0Czcn9njpPYevhBcbX9JZxtAZfmpJHxS9jNX4I3+Y

class S {
  static name = "S!";
}

为什么没有静态类?

ct1rCqbkp2fUuUWwldXf5fgrhU3JXJ5fjdPwWSSJ0+orYtrJCjULc/nKVn9Gm4pwuLtm8BbEoaVE2VfhDHihqaMn7VWxKeRc1/FT5oIf85YZAednsUD+lw2Sv77QQogEYjgWobLuR41Vbs0YbUtNRw==

6tFU5hQZZ9ZWvq4fuhOu+NfBsKd02PdjI/MUwngcRS7Pgx9u9vgjclzcnXkxfQBhYmmsVvEyghteSHkeWLRizRm1bLJNTpWkXTo97Dk00yotUj/YfLzL/Kks5j2atewwKp9XPUmFrPFoyyMXEOHF3YIrP5NEqAqAAsKHaWruKcT/kSnlV8EpBjQq17QV7Hab0f6GBXwkkYNnbscfK37Bl2ic6D/4FV9uVGI61hM1z+TtiiHeQTbDskxiza1NGxHKxY8T/sWMKfcoTGC5VE0JB0btmvRdSSR+DkRtvhBlcnWYTdGbRSahcLrK1a29EzXx6Ym0dMTFajRT13hfhhFcjw==

DbnxWGyfDt2A7LHgNNqUbwzhiDhyxPudsym90QEpW+uMaTDRSx84ICha5Y7lHhPGkmLm5eWFwkVJf5SqStm4NM4Q4yid3JspDTB+Rfnu7APOt6HRk/sA+FMZD+Eg+H+F6ZVvwyuQwNVamTrkqjfjh9O/C1YC+iHFl6D7S6MmiIC9vopdHCr4ZVIKY7gORjP6

// Unnecessary "static" class
class MyStaticClass {
  static doSomething() {}
}

// Preferred (alternative 1)
function doSomething() {}

// Preferred (alternative 2)
const MyHelperObject = {
  dosomething() {},
};

static 类中的块

Q9wWbTxHVDFvnseYlJoGZJ+t194sAnmgW1cKINnhtm22nV6hsdiLbikEjCvrcED8WEWklC3j/aMrqX20XYHaXUI7Z1Y6f6XPZx1xJmDYLow5dABAMJZnk6YDW1E0Gc6Ie/vw4BjnTk5OTlVyNGn58GLhyO94FWx7yn2YRz0cZYU1bq8tpv/DK7bPbZuQy1wDHu14YTk891AFSQPs/0Nsrl+MWR+w0CJjNVT1gne4I+FjNe2riezskvMv1mgSlZo5kQw/rWcMFSTSGTO04NyS0Jrx7gxkjn/JsFqiS+DdPApsDdNeLADB9z3Cp/rSOfyIsICygq32ge/BLEtbaZ4QOtAerqG3Yw4CiNj6kVQodJ9yPySVEDJSqRFOLo/AtQgU

declare function loadLastInstances(): any[]

class Foo {
    static #count = 0;

    get count() {
        return Foo.#count;
    }

    static {
        try {
            const lastInstances = loadLastInstances();
            Foo.#count += lastInstances.length;
        }
        catch {}
    }
}

泛型类

76+Z2S7hpsWDvO35rJR07pTAnlw48MBF3hvDhJRZbPZvaEXf9LqMmOFEmlN0zdCJZSSGyAadK2hNRgWRNzrJsgvjzNNynEVY3uO/IfJ5PMIzb10pqzbffgFZqDeZskjzQcT7tIUL1+3dWUjKeV69HhWhGr/rWV9Izyg3M8IaeTA6wxZkzeKI+/8hAyomNqTBpKtKF62do7xZfWmCu4daetd/WR6NuTLKTnqBuJBD7Fw=

class Box<Type> {
  contents: Type;
  constructor(value: Type) {
    this.contents = value;
  }
}

const b = new Box("hello!");
//    ^?

3kIZqTjlXQan440MI+eMPXzkmQlqAGVziy4f8d0W+mzuNyACyTv4nEM2IUEWPGElbqUSNyOh4ze9mX4As9UTQw==

静态成员中的类型参数

p/Gj29BoRR1pRt5UBZRMjkMkA0Gwo+8uhQ44xmjLEwxNH85EQmFm8NIpp/tdB6btrvBMAepVz3PHYOoOFPuz2Q==

class Box<Type> {
  static defaultValue: Type;
}

Yf2kKKdFfK0KH73sqNMmuBOPUokbCg6ntgGwXwU8N8wo61fgQg1TI4SJIWti3U8MMvDTqlCff8cQoHV2MWoNi/rYasGfeMrcX4vSiGRgCW/hVfwdLhVdY15GnzYoJv0fK0bq/+lbHclOl0DlEX6Gr0n3O7cbdyIwJbuWCS9QYQ/Hjme6XpC1AexndYY9c0sJgdMd/7oDhFIxu0fq29mBWKEaNpNJ9FgkKTYHD2+eTH1QK3cDAPKp3MyhThUcUpg4v/rhfeq3E8w4de2uDd2NQFilWbQt8z2dJBKPoTZSf8IA4aqkA7dq+Dw5iUVoJcAVHkTCYAMc2yV+SMzFtbtHBlqfld7ONYN3QgghSglN/TaRKAQ0fXTExxxr21C65WqvXCfPo3J/3tBeDAfcEDTY9d4iSiJjxuW787MH+VDvzR4uiXO0M6rASGWkvrco346LB8cR4RncBOR5KsTE1Wplxw==

类运行时的 this

FPDnirHrmqu+mWyhljYke8SY6G6gMSRpErXNkz+P2q9oriwXv5DNJ2DjUEVhfoLlw8noL/tBLwMt2+itv6+xZRkeWH+9HxUveP+qBI2H7xWgqXthU0B/VokRfiDUBJTp7+O/c9R14I/aQ6ReC2MeAfat3NNhyucwRrs8kfXzASc+nawz3+bbJh6cxBUT8LiOADC4nnRXZmieW7TIgN1OIw==

Ii1WFNVb0ZNuNbQpGOYw3gtUXxtaEjLXBxnlEThHJesT0eYCzNQSku1SDlKLQCO9Qeb6r5DLcPXUVE9Y3lcA0A==

class MyClass {
  name = "MyClass";
  getName() {
    return this.name;
  }
}
const c = new MyClass();
const obj = {
  name: "obj",
  getName: c.getName,
};

// Prints "obj", not "MyClass"
console.log(obj.getName());

oCrEtNzZZWWOGoJpIVIK5/5//WBHDGIxK8OiwEsZLshEZEHodBzRJk/uQ2gKOymKztuuryxD/oXANWCIn9uQIXGIwDyLl8Jdc7G1zr/X4kG/+ZdMMDF7g9LShIYqmsyaa080L5NXxqKrsxlZtUcf1REPpnsBL1SQnkVlDJ3dLUKLjL+qFP0MUFYLzBrgewH1l4mQAqquLz00VrR+h1MTS5CLFWv6zLu3MtYjaAzTKw6XcJNzx4z6OCGrBcv0Bhm1Qs0K8sdAjG/sh/Xhe0ssrdCXygaEdstojsVy9kL2Nv53kOXqEfIma8zpWR16tirRIbCnspLqC3QlVoG1VaAw/wlHFTBQLLvug++oFVizKUQ=

yis6Ty+/wUw5hxlMi+F+c2Uzsbdhk7OsBHJyPbBi474Ykt+NXIBNzpoC5Vhpz92aLEPUbyGcRFgOHxOKsEl/MOWNt0ZUe5hwJG8FVA5MKSATcjM7BIYcipUjwEVHcB/fPto3pL6XDgUQ2LQ4hNyfjA==

箭头函数

XSVqJSP/RULIUg2dAvhYk4/988Pp4M9pk1+R0wbCCuIcmO7+cE5G21rxJkGlEwah/aCXcDuI2O3JVqcmrvj7/szYNuBVSZbW8OhBVhHKw0sPWHa8ybt2Ui9zgyKcIhcZV6NRcb6scUz51zwomCyfEZNuUe6gk0zp11b4vY44mEx7h9ON6zVkRLuRBaKkeDFvTHKrI9ncXN9nrAJqJrG+TA==

class MyClass {
  name = "MyClass";
  getName = () => {
    return this.name;
  };
}
const c = new MyClass();
const g = c.getName;
// Prints "MyClass" instead of crashing
console.log(g());

dnUwkJjUAHdtN1hgBQDptVCmqPaXSKYoZ9SdASFqlCI=

    FxvHNdKk8lVq0TgU0OMIHUyH9HP5D9Y4pBwRy3mzmQR3sz2kFfCFvMONtMlpcvo6E81d4CGi+aSS3iROzTF9Ifi20JKyffwPBA6Zoj4+ZwdzgY5mheIfwTGUKVkNpt8cZwZnvPctLeQ/g8iHz9EOB9xwvkrhsmXNbh3WZdGY7wiViMHvHiNcoPIsOaPEkS7Yuza/dwHrS4yhYy0ILAn3rnCCXnm9e6CxQS0ceC80orplr1ZcR0UxtCbWHeG9S/HW2OtGkh/RNd/SnOEd8Dw6o6bzHezEICkmSsVKA2oYoSEktQYtB8CV1rRwuActnmcViiBxwl3ozlUuX+mF0HAcp9uNVdY0Y2INGTiN09BoYQBdndnQWkloZG7I2GqGF5JUBwq2qtEwgSSaebbjNAflDTNYdz8kPD7JqspCmp9xZi39KxWWJ/I+iM5SkDbIUmMjQAFFZ7ARVqSpEl7Qr7YYwlCqq6X1eU5t+Aau0BnojGH1SaVsYTKigs2NIOCZ6ahI

this 参数

dJ1sLgtMwILJP0N5SRlb60yQkAmpAfWPVXXTpFuGJcs2MBqfzSuOVkbPvw44r2CNMGQRm1qBdPvLO614bdzE2I3aUxCwU9bemppWhxG9MbH//rPhA8/+gWYtNgHw44fi+pc0Wa44O+vT9Iky+MpLnO4l7e2zBwI/VWHQ79qf63YoveoR4Cm5gCNNXoOz+xV/f8JpVxlXMYmPYnPz1qQxEA==

type SomeType = any;

// TypeScript input with 'this' parameter
function fn(this: SomeType, x: number) {
  /* ... */
}
// JavaScript output
function fn(x) {
  /* ... */
}

p2WfKT4MUN59V4TuL0TFob3nXCgNIXO3a/1lkgiBnZcI0Z2LygsGiKKh0fR+NOc+a4r4Foo1ipwMv8Q0K76r1Xp/LE6mPZUbJA/cvXpvpHlwgMMrcLAaEY33nLzDJBQhMZRsWK/lhICTNGo2tTKKkr1K1xPPc6me190YkZampGBkVIcsOwr8MRR66QdbdXaw8TbXeHNvJgFvO6DmImlF7jAOPMLjmuO6Re0qVecqJzmsbQGBL6kqilBhg7Jeen8sUZIldKLDlbsrkDb0WMLujw2uHsZhKa6TXumkHiDPFGg7YSfAgMh8PHaIXIqTrYv/

class MyClass {
  name = "MyClass";
  getName(this: MyClass) {
    return this.name;
  }
}
const c = new MyClass();
// OK
c.getName();

// Error, would crash
const g = c.getName;
console.log(g());

xJZRqu29V3fU6GVcKOTsvtPEcQR14FkqjnBFtAw+/ZNmvpi9FNBqmsuNXZ57Fft1L4lr8g0wyqiEHc8KALWGAw==

    4IFVLexSH0kmgUy2TDlSmpUDs3ULaFttcO3xn72l7XmO89zV9VrI9GL0GzlEhbraD30aESO9Ob/KUua3sz1WBc9kxFpBRIpSaXDs/mPWnQrQ+QQeyhr4lLEhe/pEfQ7CM+igSlzZNo6vdAxsj7am6fO1uypwD8/KiccajatuGP3mgHk0h2hgq9zjtci3SO0qXgKKnObvcrSo+d3MOuy3ToNayMHsIJj1gLInt5spHfH/6MsVPiXw69+N7L03heG4tPkRwCB8mM5XSi0uk4UQ/L1tT3Gd/W8KCjTPsvj7Ofp8wZ2+fZHcsSVyqOkrejmWSsDMkf3EPAarObcII1eLmQ==

this 类型

WiqC+iF0f++ww99NsLGs9STjiLFtIj/liQjVk81Kki0yuJnoG8KWEW/Hmj/cBU8Q9frQBLv2ZwyuEhHMWOmo1GVrKDggvODjqJT8C8zmxKPfrSgvf9PcF/84edVje3skvtnn3MdcoWE+Z8dUBacG+o7DJ+jC4MktTbdGi7AWviARMmf/8M6u4hCJEZuntUxQ

class Box {
  contents: string = "";
  set(value: string) {
//  ^?
    this.contents = value;
    return this;
  }
}

6lubl2JaR5lvr6pwArPEGBcOg04EsEER/RNDvavuOKBD8mOrugqm5gQdm9LZ0P6o6gk7M6dLMOCdTxacglIYt2hfGHtKOhDJDEynqH8G8Rz+7f4Z03Y41EvlKzMZ16R7bVpxuvIuQ3whz4KLZdGXacyM4oaXVgM6vC20zQhgcuEwutXXCeNoZUGk8R2FD+n+38jHERlrVUK7rF3WnSvG0evrPaohvUFn/M6UcPVHIb8=

class Box {
  contents: string = "";
  set(value: string) {
    this.contents = value;
    return this;
  }
}

class ClearableBox extends Box {
  clear() {
    this.contents = "";
  }
}

const a = new ClearableBox();
const b = a.set("hello");
//    ^?

u2R7eqNF6iubeVRW7oFLtsSa6BT+DdQQBRGR0wnQft5FiR6jbCVudNX17lXP2A+9y7ZRrW6CET97JVAYdt5hdQ==

class Box {
  content: string = "";
  sameAs(other: this) {
    return other.content === this.content;
  }
}

knvcVjhSW41oUmMN2a0svzptZsn7poDPLeigkcxBLPOp5cHnhAP4TTwEyGLdoxpulJds3Lr0w4K034CiNvw2FqbiSzZjatOv1Hul1MJnHMg7AcVtXT33CUO8uJLLb0Ma/WS+6jRVzLrbNnCpdw/h+x0jU4H8DbHNClxlJGOV7Mw5Zsu625iNWwkx8CMKU3W3AWIBhkKnR5t44wRYaHC81GtI9eEWNJ0RdRwCm9f6CRE=

class Box {
  content: string = "";
  sameAs(other: this) {
    return other.content === this.content;
  }
}

class DerivedBox extends Box {
  otherContent: string = "?";
}

const base = new Box();
const derived = new DerivedBox();
derived.sameAs(base);

this 型防护

kPx9eT31AI1KDQZtX0W2BEXBOs72Se2EnR7taTdRDI7MWZ065Zu17U8em6EdpIgi4bO157T7H6a4Wp5Gv33bMRQguTojp4dB21v5GnV/Fn3VoEHSMTBDJJ7eMYalxUduotDt1al44h8qJB0wXwpQdXaP+3fAPsVxtAdej5/ptbF/nKrSk2mCw5+Up6142CYF419CqBtdlqSxFzGspCHCCIv9IiPT5RCLBoDJ2p7bO/m1uKnfe9CSuId76PInIiTsM1UznzF2sgJFzz/IereKBUrTn7A0XY65019pHgBgANs=

class FileSystemObject {
  isFile(): this is FileRep {
    return this instanceof FileRep;
  }
  isDirectory(): this is Directory {
    return this instanceof Directory;
  }
  isNetworked(): this is Networked & this {
    return this.networked;
  }
  constructor(public path: string, private networked: boolean) {}
}

class FileRep extends FileSystemObject {
  constructor(path: string, public content: string) {
    super(path, false);
  }
}

class Directory extends FileSystemObject {
  children: FileSystemObject[];
}

interface Networked {
  host: string;
}

const fso: FileSystemObject = new FileRep("foo/bar.txt", "foo");

if (fso.isFile()) {
  fso.content;
// ^?
} else if (fso.isDirectory()) {
  fso.children;
// ^?
} else if (fso.isNetworked()) {
  fso.host;
// ^?
}

280oD+IxJnXWty0eiYYnJmDSokA4r8YL0F967mf2lUjimgc5Gz/SW8Vf7qoHhog3TBKbheDHHGHdmZstJ/U+7wWmSQbLoaRAnLXj+6xFXewZxm7kzmDJ98Asxs6x/axPoNpG0U9rpr2bIxkSiwTmiYa9mRjMQxy+/sSwtf9xhY0T50WI1pGEw6iPC9DKgWx95ybiRv6xO3a4DsNPQPS9grTOXu9U8Q/HdGcckgd6sQkNxY33n9qvIKpt+80IcSqwB7G4TWIcohf0UtE5TXk8/8uhHAJIDqi0LzZyginH5bI=

class Box<T> {
  value?: T;

  hasValue(): this is { value: T } {
    return this.value !== undefined;
  }
}

const box = new Box();
box.value = "Gameboy";

box.value;
//  ^?

if (box.hasValue()) {
  box.value;
  //  ^?
}

参数属性

nbLZhieivE0STxaJk+1ZKmr0wtJKcZYfnQiRKwAq+2EyeLW4JcHqnLdP2eIos5TBrfU95l5/AOwAetpqfGqP61SWQZdi70qwaLkRZIbEgG6MykSaa+YJL76NmN84h/WZ8fUek+dd0rvtkY195vtSEEfI17QGn6sLTEKHAIMdijYqgI7eUvGgST+oo+WxH5feOP3J44KYIQZIX0wu3mdq9vfAcWKEIB9tMXh0Nlvl8WhNPbm4sgXe+jEpqXGCYI2OPwt6URVng1+AFpgcBlh+OuN4mTLIsXRQBj08HK7l2aFED8Dp8hxf9UzEZzugkdLAlkeJkhExRBnNLRWGUnZfn4VaIke9pSaOrEbyZ9X3cA1d+BxSqa1VUPQP+CWG3KQ7wrfpQELF2Ti4kIMDH1xQuNv6rMMV0DE3CVtyM+Y9EQ+MAlWv4T9iw8vYjnHW3FANg8axx6aaDj89A20WpU20xg==

class Params {
  constructor(
    public readonly x: number,
    protected y: number,
    private z: number
  ) {
    // No body necessary
  }
}
const a = new Params(1, 2, 3);
console.log(a.x);
//            ^?
console.log(a.z);

类表达式

7YPvujjdd17yQkdvipQkdCE6YPEVqSlk0wIiywg2drDJ/nBqERlk9S70D3ufcwKZx393TybCEn7pn8oiSO+pQMDin8PRoD5RjvogSEQkMUOYMDhKd+3cI16z24srCEJ5wD3uH9twwGM2g5D0APKOEPBK+z1ewVHOldO1WomWuzdBAHCDfcWQgzuIigp4rc/8uclopinU62YYMOHdijB8pyVb0wdNAL8s5MvP5f2ArCs=

const someClass = class<Type> {
  content: Type;
  constructor(value: Type) {
    this.content = value;
  }
};

const m = new someClass("Hello, world");
//    ^?

abstract 类和成员

/L+9UZZ4Thh+rZrf2bUN3GPnQA2MJu0BWSFYDbK+ELyrUtNyrLWxmsuCZEX6jR+Y2HpUnq/5gIxR3mk4T9CVeg==

6klHjrvKDjDLTHkMcf1eKbwCcZDOsGFz6/q7hscCK1oSsXB1keSXX+0HOvq0v+kwtRCvedEC4xvxJ0vrFwae6QjiFF49615eaj4keNq4gS/WYZBrnY+Poh1Fz8821h7VvGkM5/wo948+QwNvn2SWWcN4ZDSrTa+AJ23znU7U7Wg=

wpOJ+5UjfNK6HR8S7VvZzdzS+Gl0ph+HgXMUtmMFJWwv9FpyN+EWMbLRs9UOQEoz+QcfC8z33tyZ3czrzJIk2IJ5I84uIkvkZ9hN/+pPNkcSVRUbFqd+bk1jM8m/tnpChpx62Amy9/omhYamtlK/4ddwojSrxxYZQmS+VRp2qiDGm89zP1gMG36raOwJPAWN

vjaxXjCVO6B74jx4+QMSVDn5vamjhWRi+Ppp39fFHu0=

abstract class Base {
  abstract getName(): string;

  printName() {
    console.log("Hello, " + this.getName());
  }
}

const b = new Base();

tWxweJQLPu/n/qLzS8w8s79mWiweeJu19XVS8/IB67z1zmLCly1PhgTZNkIXZ7UGeEbX5QrP9WPYiWZINVKfl6ktkQZD7i33+tuvd9PAFIOSl1ntO2cx/bajJ3ITYl7OGNNpbvZzK09+wRVN9Snd8O4NLsvl4t2YPEVQ8S3vdwww/Q83D3D3mQ+nNy/IbjzqWsxDl3Ps8Y16Wcz4yC+PWA==

abstract class Base {
  abstract getName(): string;
  printName() {}
}

class Derived extends Base {
  getName() {
    return "world";
  }
}

const d = new Derived();
d.printName();

w/oBSZW0QUGsnTy+zkmaIzun5SNHQJAUYKjDTpZkNPDJQE9VLE2uBa1I0B4fcGu1Qkbef4zKB6SXMx1AYcditBj7ddMoPzYGlDgQB5R/yY5lnxZl2CLcJdHAKsfoq5wH

abstract class Base {
  abstract getName(): string;
  printName() {}
}

class Derived extends Base {
  // forgot to do anything
}

抽象构造签名

/5QJYffZA9iGQIQBVIZY7M6Wzb9M422s7PGfWhYdkjlIS4lmSsQDyk/tGFDs6bri29MvkFFsQsnG4JI9dqOfeBfh3EGi/OCQB152xIHa7mB6CLG3Iasa9rMluOqWr+fFNLFzthNnaOUpHAaG0n25aw==

CYHjI32PWqBKZqjSjC3IMhc8HpCfsq1/sM6p0WWCMzFe62traU9Wbx/hGvR4vpnG

abstract class Base {
  abstract getName(): string;
  printName() {}
}
class Derived extends Base {
  getName() {
    return "";
  }
}

function greet(ctor: typeof Base) {
  const instance = new ctor();
  instance.printName();
}

4yXx6gyxd/desl80k47BEAuNqVOeiRSDGJGfTYtKR/soJb6h1mvuEt5si4hpe0zYf48s6oDISoiKG+S+jXc/UazZwOk7Tgdrge4+hfTk1xDbKYU7gvnOAwq1ilpsepjT6+3tAyNW6GlUHXwASRAjIeQ4v7DTuzVKVaQze88iwW85by+fb4HJalnjLaudWAg9pu+qMU1+1ZO9GVR8FiTh+dAIeWEA6+eyM5U3WGrZw2nKXwdIB9yNOmUYbuAws1X+8/c096Es0Yi3xtwK5hYxyg==

declare const greet: any, Base: any;

// Bad!
greet(Base);

Aa8aM/DlIVva/yRfx5GoRDzE1GCJoz/a1gh/anZfO1Y7/FATN8DbKwMIfR8MNjILqHBxfVhhWJZQ4BovQBinmquICbxiUJ/TYhvFoP3K+S8=

abstract class Base {
  abstract getName(): string;
  printName() {}
}
class Derived extends Base {
  getName() {
    return "";
  }
}

function greet(ctor: new () => Base) {
  const instance = new ctor();
  instance.printName();
}
greet(Derived);
greet(Base);

iqP7PWlexPwLfPVz2Zsgb6pPtSccjvKiX5RfaIydUuhGvZIhzY4bf93UlPLqvsisMWA6nViWFXg6av3Dt36WvNd1+vhO3vOv9fhMEtZGuMxWvaAszCUv6g7Ni6gV6mWepLbdh/5ZMDVHV8R3OrKCQyq7YzIyEhCs+aD2blywEFEUXfQgVeCBdKCPRbPDnVbYJQR3Te/rD+RKdym8SdyInw==

类之间的关系

EWp1j9kHvjcdWxU0acM1KzYwuSylqquDuJNAiNF0p5reUY9m26ysl2nq44yMFrpXXMZpHdbG1w6qxTgIICG0YHvpfzW2U5ei5gFzWd/rAd79eNeAqX1AJsvqDKhpYtbB

SWYX71oJZlS1+N2PFFDlm6dwFFVFboW5sibXrXSplw9fq2iCib48tHC+p/D7Ln3psi3dKFfjFzuLR+zasNCgcAk+8imza/iZHz2jhbNIW0g=

class Point1 {
  x = 0;
  y = 0;
}

class Point2 {
  x = 0;
  y = 0;
}

// OK
const p: Point1 = new Point2();

2tZmIBdCfeDgLWJ5Eon0aPacAc0LZJD2s2dxPe2ep1Djq469KtylErHVPAtlYBHNdK7XQq6zYgIge/5/HT0uBaX2bl45zynl3NGCRmRNcyU=

class Person {
  name: string;
  age: number;
}

class Employee {
  name: string;
  age: number;
  salary: number;
}

// OK
const p: Person = new Employee();

feDAayXIIE15H7RU2NfWJLW7vWSXU2Y8KkuE/zY97uLas1KYwt2IuBSXwLv+unJ1fYw8jd3ET4H+o8na4qoU+pb1U0076U8XtV0YzM+i8LA=

pZLzkofCze+L1bDhRyoYDyBAPz8NlE4pY82JPUjeEeeXBVkwtUHCjiMkl74pNI8bh1VV9nbibpJvCU4tYRUXlYmhn+ADnqkhnzuXud+aTunxIkajrJfIbVvg+pmPZQqb5PESHNizOpCrEyxlKZ6ZLKYDLZI/isjrA0iHJ8MFod/dZRsw+4asC67VnJmSq2Ap0CqoJyLn3epk08V2y4R52K7GxmOO6jSOHJyD9d21nEICaigayyebGLyBgPO0Xe9czpkboeRdn/zr8e3Qnx4+Ig==

class Empty {}

function fn(x: Empty) {
  // can't do anything with 'x', so I won't
}

// All OK!
fn(window);
fn({});
fn(fn);