Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript Overview Digest #139

Closed
towry opened this issue Jun 2, 2020 · 4 comments
Closed

TypeScript Overview Digest #139

towry opened this issue Jun 2, 2020 · 4 comments

Comments

@towry
Copy link
Owner

towry commented Jun 2, 2020

Release notes

Posts

@towry
Copy link
Owner Author

towry commented Jun 2, 2020

@ts-expect-error

That’s why TypeScript 3.9 brings a new feature: // @ts-expect-error comments. When a line is prefixed with a // @ts-expect-error comment, TypeScript will suppress that error from being reported; but if there’s no error, TypeScript will report that // @ts-expect-error wasn’t necessary.

ECMAScript Private Fields

class Person {
    #name: string

    constructor(name: string) {
        this.#name = name;
    }

    greet() {
        console.log(`Hello, my name is ${this.#name}!`);
    }
}

let jeremy = new Person("Jeremy Bearimy");

jeremy.#name
//     ~~~~~
// Property '#name' is not accessible outside class 'Person'
// because it has a private identifier.

@towry
Copy link
Owner Author

towry commented Jun 5, 2020

This type

Related issue: microsoft/TypeScript#3694

example code:

class Base {
  handler?: <T extends this>(b: T) => void;
  onSomeEvt(handler: (b: this) => void) {
    this.handler = handler;
  }
}

class Child extends Base {
  init() {
    this.onSomeEvt((c: Child) => {
      c.work();
    });
  }
  work() {
    console.log("work");
  }
}

Playground Link

More complex realistic example:

import TreeNode from "./TreeNode";
import cloneDeep from "lodash/cloneDeep";
import set from "lodash/set";
import { Dictionary } from "../../core/types";
import { Config, Model, ReactiveSetter, ITreeNode } from "./types";

export interface ModelPayload {
  id: number | string;
  type: string;
  titleEn: string;
  title: string;
}

interface Options extends Dictionary {
  // Some framework like Vue need to manully trigger reactive change for value like Object|Array.
  reactiveSetter?: ReactiveSetter;
}

export interface IRenderItem<T extends ModelPayload> extends ITreeNode<T> {
  options: Options;
  attrs: Dictionary;

  isRenderItem: boolean;
  id: number | string;
  title: string;
  type: string | number;
  setAttr(keyPath: string, value: any): void;
  clone<T extends this>(): T;
}

export default class RenderItem<T extends ModelPayload> extends TreeNode<T>
  implements IRenderItem<T> {
  options: Options;
  /**
   * Extra dataset. maybe we should use the name dataset, but for compatibility, we still use attrs.
   */
  attrs: Dictionary;

  constructor(config: Config, model: Model<T>, options?: Options) {
    super(config, model);

    this.options = options || {};
    this.attrs = {};
  }

  get isRenderItem() {
    return true;
  }

  get id() {
    return this.model.id;
  }

  get title() {
    if (this.options.locale == "en") {
      return this.model.titleEn;
    }

    return this.model.title;
  }

  get type() {
    return this.model.type;
  }

  setAttr(keyPath: string, value: any) {
    set(this.attrs, keyPath, value);

    if (this.options.reactiveSetter) {
      this.options.reactiveSetter(this.attrs, keyPath, value);
    }
  }

  // here ... 🍜
  clone<C extends this>(/*options*/): C {
    const cloned = new RenderItem(
      this.config,
      cloneDeep(this.model),
      this.options
    );

    // this seemed important.
    return cloned as C;
  }
}

And this: #138 (comment)

@towry
Copy link
Owner Author

towry commented Jun 8, 2020

"unknown" and "any" type

The type unknown is a type-safe version of the type any. Whenever you are thinking of using any, try using unknown first.
Where any allows us to do anything, unknown is much more restrictive.
Before we can perform any operation on values of type unknown, we must first narrow their types

https://2ality.com/2020/06/any-unknown-typescript.html

@towry towry closed this as completed Jul 16, 2020
@towry
Copy link
Owner Author

towry commented Sep 4, 2020

Module

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant