Typescript
  • Introducão
  • Primeiros Passos
    • Por que TypeScript
  • JavaScript
    • Igualdade
    • Referências
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Futuro JavaScript Agora
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Project
    • Compilation Context
      • tsconfig.json
      • Which Files?
    • Declaration Spaces
    • Modules
      • File Module Details
      • globals.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Bind is Bad
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page

Was this helpful?

  1. TIPs

Type Instantiation

PreviousCurryingNextLazy Object Literal Initialization

Last updated 5 years ago

Was this helpful?

Say you have something that has a generic parameter e.g. a class Foo:

class Foo<T>{
    foo: T;
}

You want to create a specialized version for it for a particular type. The pattern is to copy the item into a new variable and give it the type annotation with the generics replaced with concrete types. E.g. if you want a class Foo<number>:

class Foo<T>{
    foo: T;
}
let FooNumber = Foo as { new ():Foo<number> }; // ref 1

In ref 1 you are saying that FooNumber is the same as Foo but just treat it as something that when called with the new operator gives an instance of Foo<Number>.

Inheritance

The Type assertion pattern is unsafe in that it trusts you to do the right thing. A common pattern in other languages for classes is to just use inheritance :

class FooNumber extends Foo<number>{}

One word of caution here: if you use decorators on the base class then the inherited class might not have the same behavior as the base class (it is no longer wrapped by the decorator).

Of course if you are not specializing classes you still have to come up with a coercion / assertion pattern that works and hence we showed the general assertion pattern first, e.g.:

function id<T>(x: T) { return x; }
const idNum = id as {(x:number):number};

Inspired by this

stackoverflow question