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

Contextual type assertion operator #2876

Closed
RyanCavanaugh opened this issue Apr 22, 2015 · 9 comments
Closed

Contextual type assertion operator #2876

RyanCavanaugh opened this issue Apr 22, 2015 · 9 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@RyanCavanaugh
Copy link
Member

A contextual type assertion expression, <?>, is like a regular type assertion (e.g. <string>), but asserts to the contextual type of the expression.

About half of all type assertions can be rewritten this way with no loss of type safety.

Example:

declare function setDivText(div: HTMLDivElement): void;

// Error
setDivText(document.getElementById('myDiv'));
// OK, but a lot of typing
setDivText(<HTMLDivElement>document.getElementById('myDiv'));
// OK and easy
setDivText(<?>document.getElementById('myDiv'));

It is an error to use a contextual assertion when no contextual type exists:

<?>foo; // Error
var x: number = <?>foo; // OK

This should nearly eliminate assertions to <any> due to people not wanting to type out large type literals.

@RyanCavanaugh RyanCavanaugh changed the title Contextual type assertion operator <?> Contextual type assertion operator Apr 22, 2015
@RyanCavanaugh
Copy link
Member Author

@benjamin-hg
Copy link

So in contrast to <any>, <?> would just narrow down the type to the required derived type?

setDivText(<?>"not a super type of HTMLDivElement"); // expected to fail

@RyanCavanaugh
Copy link
Member Author

Correct

@stephanedr
Copy link

Instead of <...>, I often use a function which checks the object is really of the expected type.
So:

function cast<T>(type: { new (...args: any[]): T }, object: Object): T { ... }
setDivText(cast(HTMLDivElement, document.getElementById('myDiv')));

I would be really interested in using your <?> shortcut, but I don't see how I can in the context of an intermediate function call.
Ideally I would like to write something like:

setDivText(cast(?, document.getElementById('myDiv')));
setDivText(autocast(document.getElementById('myDiv')));

autocast() would have access to the contextual target type, but also its constructor to be able to use instanceof.

@RyanCavanaugh
Copy link
Member Author

Function arguments are contextually typed by the corresponding parameter types, so setDivText(<?>someElement); would work (assuming function setDivText(x: HTMLDivElement), of course)

@paulvanbrenk
Copy link
Contributor

👍

@stephanedr
Copy link

Indeed, but my case is different.
I want to go through an intermediate function to confirm someElement is really of type HTMLDivElement.
Today I would use setDivText(cast(HTMLDivElement, someElement));

I would like to be able to perform the same, but without mentioning the corresponding parameter type.
Something like:

setDivText(cast(?, document.getElementById('myDiv')));
setDivText(autocast(document.getElementById('myDiv')));

@Griffork
Copy link

👍 for <?>
Perfect solution for a frustration I had.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus Declined The issue was declined as something which matches the TypeScript vision and removed In Discussion Not yet reached consensus labels May 18, 2015
@RyanCavanaugh
Copy link
Member Author

General take on this was that users are unlikely to be able to correctly reason about what this operator is doing (given that most people don't work on compilers all day like I do 😃 ).

Some better solution for an "automatic downcast" would be neat, but it's hard to imagine what that would be.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants