Typescript: Need documentation for InstanceType

Created on 27 Jul 2018  Â·  15Comments  Â·  Source: microsoft/TypeScript

I've been banging my head against the wall for hours trying to figure out how to extract a type/interface for an object, and someone clued me into InstanceType which is apparently not documented.

It would be awesome if some TS wiz could add this to the official docs.

Question

Most helpful comment

@ducin @ffxsam Usually you don't need InstanceType. If the class is a regular class declaration you can just use the class name to get the instance type. There are however use-cases for InstanceType. Sometimes either the class declaration is not itself accessible (with mixins for example) or is unknown (when using generics) or is a class expression. Here are two code snippets where InstanceType is very much needed:

Mixins:

function mixin<T extends new (...a: any[])=> any>(baseClass: T) {
    class Extended extends baseClass {
        public extendedMethod() {}
    }
    return Extended;
}

let FinalClass = mixin(class {
    method() {}
})
let o: FinalClass // error FinalClass is not a type, it's just a value
let oo: InstanceType<typeof FinalClass>;
// Usually for convienence I would just add a type alias, so as to mimic a regular type declaration
// type FinalClass = InstanceType<typeof FinalClass>; // remove comment to remove error on o declaration

Factory Function:

declare function create<T extends new () => any>(c: T): InstanceType<T>

class A { }
class B { }
let a = create(A) // A
let b = create(B) // B

All 15 comments

If you hover on the declaration in your IDE you should see the docs:

image

You should also find them documented in the release notes: http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#predefined-conditional-types

Both of those routes are insufficient. It should be documented in the handbook main docs (not release notes). The point is, I never knew about InstanceType until someone told me about it, and it was something I really needed. I would've known about it if it were in the documentation.

We do not document all the types in the standard library in the handbook. for instance ReadonlyArray is not there, nor is ReadonlySet, IterableIterator, Promise, etc..

Interesting. But then how is one supposed to learn about these? Where can I read up on what IterableIterator or ReadonlySet do, along with examples of usage?

We have relied on editor interaction for these. the types usually will have a JSDoc comment on them explaining what they do.

That's useful for sure. But the point I think you're missing is that nobody going through the docs would've learned about InstanceType. And you would have to _know_ about it before looking for it via autocomplete in an editor like VS Code.

The TypeScript docs need a comprehensive API reference in the website docs, IMO. And I'd be happy to contribute, of course, but I'm too new to TypeScript.

@ffxsam I am totally agreed with you, i've been into the same situation.
@mhegazy I think TypeScript must have an api reference document, and not just the getting started one. Not everybody is from JS background, infact people ( like me ) would be taking up TS just to avoid JS, as JS is conceptually very different from a language like C# and is not very well supported by Visual Studio.

@mhegazy I believe the difference between something like Promise and InstanceType is that Promise is well document as part of ES. As a developer, I know that I can use anything that is part of ES, and there is probably type information for those things that I can discovery through my editor (e.g., look at the return type of Promise.resolve(...)).

However, for something like InstanceType, this is _purely_ a type system construct and not mentioned or hinted at anywhere in any ES documentation such as MDN. There is no way for me to discover this construct _other_ than reading the release notes or having someone tell me about it.

I'm of the opinion that constructs that are unique to TypeScript and don't have any hints coming from ES _should_ be documented in the TypeScript handbook. I tend to agree with you though that it is unnecessary to document all of the standard library stuff that derive from ES things.

“Utility Types”, including InstanceType are documented in the Utility Types page in the Handbook, but it’s hard to find as it’s only accessible through GitHub and not the site. There are two open issues requesting that it be added to the sidebar:

https://github.com/Microsoft/TypeScript-Handbook/issues/945
https://github.com/Microsoft/TypeScript-Handbook/issues/914

What is the usecase of the InstanceType? Given class X, whatever it is, we've already got X as a type. InstanceType<typeof X> // X - so what's the meaning of this type? All other four conditional built-in types make perfect sense to me.

It's true, InstanceType seems kind of pointless now that I have a bit more time with TypeScript.

const spot1: InstanceType<typeof Dog> = new Dog('Spot');
const spot2: Dog = new Dog('Spot Evil Clone');

spot1.bark();
spot2.bark();

These types are exactly the same in the end.

@ducin @ffxsam Usually you don't need InstanceType. If the class is a regular class declaration you can just use the class name to get the instance type. There are however use-cases for InstanceType. Sometimes either the class declaration is not itself accessible (with mixins for example) or is unknown (when using generics) or is a class expression. Here are two code snippets where InstanceType is very much needed:

Mixins:

function mixin<T extends new (...a: any[])=> any>(baseClass: T) {
    class Extended extends baseClass {
        public extendedMethod() {}
    }
    return Extended;
}

let FinalClass = mixin(class {
    method() {}
})
let o: FinalClass // error FinalClass is not a type, it's just a value
let oo: InstanceType<typeof FinalClass>;
// Usually for convienence I would just add a type alias, so as to mimic a regular type declaration
// type FinalClass = InstanceType<typeof FinalClass>; // remove comment to remove error on o declaration

Factory Function:

declare function create<T extends new () => any>(c: T): InstanceType<T>

class A { }
class B { }
let a = create(A) // A
let b = create(B) // B

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

@dragomirtitian

Here are two factory function examples:

Below exmaple is what you shared:

declare function create<T extends new () => any>(c: T): InstanceType<T>;

class A {}
class B {}
let a = create(A); // A
let b = create(B); // B

This is my try:

declare function create2<T extends new () => any>(c: T): T;

let aa = create2(A); // A
let bb = create2(B); // B

Both of them works fine under the type system of typescript, tsc doesn't complaint type error.

My typescript version: typescript: "^3.3.3"

So what's the meaning of using InstanceType<T> rather than T

update

I figure it out, T means the return type of create2 function is a class, InstanceType<T> means the return type of create function is an instance of the class.

I add some methods for A and B so that we can see the difference.

declare function create<T extends new () => any>(c: T): InstanceType<T>;

class A {
  public getName() {
    console.log('A');
  }
}
class B {
  public getAge() {
    console.log(22);
  }
}
let a = create(A); // A
let b = create(B); // B

a.getName(); // 'A'
b.getAge(); // 22

Above code works fine.

declare function create2<T extends new () => any>(c: T): T;

let aa = create2(A); // A
let bb = create2(B); // B

aa.getName(); // Property 'getName' does not exist on type 'typeof A'.ts(2339)
bb.getAge(); // Property 'getAge' does not exist on type 'typeof B'.ts(2339)

As you can see, tsc complaint type error.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kyasbal-1994 picture kyasbal-1994  Â·  3Comments

MartynasZilinskas picture MartynasZilinskas  Â·  3Comments

bgrieder picture bgrieder  Â·  3Comments

Zlatkovsky picture Zlatkovsky  Â·  3Comments

weswigham picture weswigham  Â·  3Comments