96 Matching Annotations
  1. Nov 2019
    1. To make your developer experience better I recommend to run type-checking in a separate process by starting TSC compiler (preferably in watch mode) in you terminal with --noEmit and --project flags.
  2. Oct 2019
    1. export function A(param: string): void export function A(param: { param: string, otherProp?: string }): void export function A(paramOrObj: string | { param: string, otherProp?: string } = { param: "initial"}): void {
    1. type KeysOfType<A extends object, B extends { [key: string]: any }> = { [K in keyof A]: A[K] extends B ? string extends keyof A[K] ? K : never : never; }[keyof A];
    2. type A = string extends keyof Person["favouriteNumbers"] ? true : false; // true
    3. type A = keyof Person["favouriteNumbers"]; // string | number type B = keyof Person["address"]; // "street" | "postcode"
    4. type KeysOfType<A extends object, B> = { [K in keyof A]-?: A[K] extends B ? K : never; }[keyof A];
    1. Let's make the example even easier. function convertDate<T extends string | undefined>(isoDate?: string): T { return undefined } 'undefined' is assignable to the constraint of type 'T' Means: What you return in the function (undefined), matches the constraints of your generic type parameter T (extends string | undefined). , but 'T' could be instantiated with a different subtype of constraint 'string | undefined'. Means: TypeScript does not consider that as safe. What if you defined your function like this at compile time: // expects string return type according to generics // but you return undefined in function body const res = convertDate<string>("2019-08-16T16:48:33Z") Then according to your signature, you expect the return type to be string. But at runtime that is not the case! This discrepancy that T can be instantiated with a different subtype (here string) than you return in the function (undefined) is expressed with the TypeScript error.
    1. async function createRequest( url: URL | string, { az, queries, ...parameters }: Params & { az: "text" } ): Promise<string>; async function createRequest<R>( url: URL | string, { az, queries, ...parameters }: Params & { az?: "json" } ): Promise<R>; async function createRequest<R>( url: URL | string, { az, queries, ...parameters }: Params ): Promise<R | string> {
    1. In the body of the function you have no control over the instantiation by the calling context, so we have to treat things of type T as opaque boxes and say you can't assign to it. A common mistake or misunderstanding was to constraint a type parameter and then assign to its constraint, for example: function f<T extends boolean>(x: T) { x = true; } f<false>(false); This is still incorrect because the constraint only restricts the upper bound, it does not tell you how precise T may really be.
    1. const renderMapping: { [l in letters]: renderFunction<l>; } = { 'a': (a: 'a') => 'alpha', 'b': (b: 'b') => 'bravo', }; type renderFunction<l extends letters> = (letter: l) => string; function renderLetter<l extends letters>(letter: l): renderFunction<l> { return renderMapping[letter]; }
    1. Exclude<string | number | (() => void), Function>
    2. type ReturnType<T extends AnyFunction> = T extends (...args: any[]) => infer R ? R : any;
    3. type Unpacked<T>
    4. infer declarations that introduce a type variable to be inferred
    5. These typeof type guards are recognized in two different forms: typeof v === "typename" and typeof v !== "typename", where "typename" must be "number", "string", "boolean", or "symbol". While TypeScript won’t stop you from comparing to other strings, the language won’t recognize those expressions as type guards.
    6. Type Guards
    7. Union Types
    8. Here’s a simple example that shows how to create a mixin:
    9. With index types, you can get the compiler to check code that uses dynamic property names.
    1. type Type = 'a' | 'b'; type AShape = { a: 'a' }; type BShape = { b: 'b' }; type Props<T extends Type> = { type: T, shape: T extends 'a' ? AShape : BShape, }; class Test<T extends ID> extends React.Component<Props<T>> { render() { const { type, shape } = this.props; switch (type) { case 'a': return <>{shape.a}</>; // Ideally would narrow `shape` here, instead of `AShape | BShape` default: return <>{shape.b}</>; } } } <T type="a" shape={{ a: 'a' }} /> // No error in ideal case <T type="a" shape={{ b: 'b' }} /> // error in ideal case
    2. type NumberType = (() => number) | number; function double<T extends NumberType>( num: T ) : T { if (typeof num === "number") return num * 2; return () => num() * 2; }
    1. Index types are really handy when you have an object that could have unknown keys. They're also handy when using an object as a dictionary or associative array. They do have some downsides, though. You can't specify what keys can be used, and the syntax is also a bit verbose, in my opinion. TypeScript provides a solution, however; the Record utility.
    1. Project is written in TypeScript and provides type safety out of the box. No Flow Type support is planned at this moment, but feel free to contribute.
  3. Sep 2019
    1. --p or ``--projectand notconfig`. it takes the path the the folder containing tsconfig.json, and starting with 1.8, it will allow a full path to the file
    1. Since TypeScript 1.4 static extensions can be added easily. The TypeScript team changed the lib.d.ts file to use interfaces for all static type definitions. The static type definitions are all named like [Type]Constructor: So if you want to add a static function to type Object, then add your definition to ObjectConstructor.
  4. Aug 2019
  5. Jul 2018
    1. This chapter is about “Basic JavaScript,”

      The highlighted annotations with the airbnb tag were made to illustrate where Basic Javascript differs from the Airbnb Javascript Style Guide and typescript tag for differences from Typescript Deep Dive TIPs.

    2. Or, forEach has a second parameter that allows you to provide a value for this:logHiToFriends: function () { 'use strict'; this.friends.forEach(function (friend) { console.log(this.name+' says hi to '+friend); }, this); }

      Harmful for the same reason as: Bind is Harmful

    3. use the method bind() that all functions have. It creates a new function whose this always has the given value:> var func2 = jane.describe.bind(jane); > func2() 'Person named Jane'
  6. Jul 2017
  7. Oct 2016
    1. April of ‘84

      Rigby's Romance evolved from the fifth chapter of the 1898 typescript version of Such is Life. In that text, the date of Tom Collins' arrival in Echuca is 9 January 1884. Although missing from TS, the date of the record is confirmed by internal evidence, such as Tom Collins’ two arrivals at Deniliquin in the closing pages; ‘2.45, p.m., on a cold winter day, nearly five months after the date of the events just recorded – or, to be precise, on the 3rd of June’ (TS 521); or ‘three o’clock on a Saturday afternoon, six or eight weeks after the date of the events just recorded’ (RR 249).

  8. Jun 2016
    1. @Component

      If using emacs tide-mode, customize variable tide-tsserver-process-environment to include --experimentalDecorators.

  9. Mar 2016
  10. Sep 2015
  11. Aug 2015
    1. In summary:

      1. Class decorators are functions that wrap a constructor function
      2. Property decorators are functions that take a prototype and property name as input and can modify the property
      3. Method decorators are functions that take a prototype, method name and method descriptor as input and return an updated descriptor
    2. let’s implement the logClass decorator..

      This can be simplified slightly to:

      function log(constructor: any) {
          let wrappedConstructor = (...args: any[]) => {
              console.log('creating a new ' + constructor.name, 'with args', JSON.stringify(args));
              let instance: any = Object.create(constructor.prototype);
              constructor.apply(instance, args);
              return instance;
          wrappedConstructor.prototype = constructor.prototype;
          return wrappedConstructor as any;
  12. Feb 2015