Repository navigation
proposal: type guards by constructor signature #1283
Copy link
Copy link
Closed
Labels
FixedA PR has been merged for this issueA PR has been merged for this issueHelp WantedYou can do thisYou can do thisSuggestionAn idea for TypeScriptAn idea for TypeScript
Milestone
Description
What does we need?
We need type guards by constructor signature.
// class decomposed. from http://www.typescriptlang.org/Handbook#writing-dts-files
interface A_Static {
new(m: any): A_Instance;
st: string;
}
interface A_Instance {
inst: number;
}
declare var A: A_Static;
// use type guards
var obj: A_Instance | Date;
if(obj instanceof A) {
// I hope obj is narrowing to A_Instance. but A_Static does not have `prototype` property.
obj.inst;
}Motivation
almost .d.ts files does not have prototype property in DefinitelyTyped.
It means almost .d.ts files is not union types ready.
I think We can't enforce implement prototype property to .d.ts files.
Proposal
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#420-type-guards
A type guard of the form x instanceof C, where C is of a subtype of the global type 'Function' and C has a property named 'prototype'
modified to
- A type guard of the form x instanceof C, where C is of a subtype of the global type 'Function' and C has property named 'prototype' or C has a constructor signature.
- when true,
- narrows the type of x to the type of the 'prototype' property in C provided it is a subtype of the type of x, or
- narrows the type of x to the type of the constructor signature's return type in C provided it is a subtype of the type of x, or
- when true,
My english is not so good. I made sample code.
// only prototype
interface AStatic {
(): void;
prototype: AInstance;
}
interface AInstance {
a: string;
}
declare var A: AStatic;
var objA: AInstance | Date;
if(objA instanceof A) {
// narrows to AInstance
// this pattern already possible!
objA.a;
}
// only constructor signature
// this pattern is very popular in DefinitelyTyped.
interface BStatic {
new (): BInstance;
}
interface BInstance {
b: string;
}
declare var B: BStatic;
var objB: BInstance | Date;
if(objB instanceof B) {
// narrows to BInstance
objB.b;
}
// prototype + constructor signature
interface CStatic {
new (): C1Instance;
prototype: C2Instance;
}
interface C1Instance {
c1: string;
}
interface C2Instance {
c2: string;
}
declare var C: CStatic;
var objC: C1Instance | C2Instance | Date;
if(objC instanceof C) {
// narrows to C2Instance. prototype is high priority
objC.c2;
}
// constructor signature conflicted
interface DStatic {
new (): D1Instance;
new (value: any): D2Instance;
}
interface D1Instance {
d1: string;
}
interface D2Instance {
d2: string;
}
declare var D: DStatic;
declare var objD: D1Instance | D2Instance | Date;
if(objD instanceof D) {
// narrows to D1Instance | D2Instance. union type of construtor signature's return types.
(<D1Instance>objD).d1;
(<D2Instance>objD).d2;
// I hope this line to be error.
(<Date>objD).getTime();
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
FixedA PR has been merged for this issueA PR has been merged for this issueHelp WantedYou can do thisYou can do thisSuggestionAn idea for TypeScriptAn idea for TypeScript
Activity
RyanCavanaugh commentedon Nov 26, 2014
I definitely get the motivation here.
One issue is that construct signatures can be generic and/or overloaded. We could probably use the union type of all the construct signatures' return types with
{}filling in the type parameters.Igorbek commentedon Nov 26, 2014
It's definitely very useful suggestion. 👍
johnnyreilly commentedon Nov 26, 2014
+1 for this - well expressed Masahiro Wakame (@vvakame)
basarat commentedon Nov 26, 2014
👍
Bartvds commentedon Nov 27, 2014
👍
Steve-Fenton commentedon Nov 27, 2014
👍
vvakame commentedon Nov 28, 2014
Ryan Cavanaugh (@RyanCavanaugh) I was misunderstanding spec...
I think this code evaluate to following pseudo code.
but actual
I think this issue is not related to my proposal directly. but I feel "type guards with generics" is very important feature.
does we need contextual type guards?
off topic.
I'm not using VisualStudio.

I want to see type of variable like this.
Is there any way use playgroud of master/HEAD in local environment?
off topic 2.
if Property_0_does_not_exist_on_type_1 occured after type narrowing check, I want get warning message ("{0} is not narrowed to {1}.") with it.
danquirk commentedon Dec 1, 2014
Unfortunately there's no easy way to get a playground with the latest bits. One hack you can do to check types via the command line is to redeclare the var whose type you are interested in. That should cause an error which will print the relevant types.
vvakame commentedon Dec 2, 2014
Dan Quirk (@danquirk) thank you! It very useful information for me.
RyanCavanaugh commentedon Apr 27, 2015
Approved
mhegazy commentedon May 6, 2015
Thanks Masahiro Wakame (@vvakame)!