You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Perhaps something more akin to google AtScript for consistency. Basically flag --rtts will cause emited JS to have rtts (runtime type system) checks inserted.
Reacted by Tanguy Krotoff, zjiekai, Attila Egyed, Tom Crockett, Joe Pea, Andrew Faulkner, webpartisan, monnef, François Cabrol, Kirill Groshkov and 1 more
I'm suggesting, however, that you can optionally enable runtime type checking on some args and not others. Or, at least, skip type checking on private methods, optionally.
Reacted by Aluan Haddad, Alex, AbraaoAlves, Maarten, Łukasz Kużyński, Jiali Chen, Artem Sapegin, Denis Malinochkin, Marin Marinov, Dan Schuman and 6 more
Reacted by Andreas, wesleylima, Alexander, Joe Pea, Tess , Serge S. Gulin, Marco Quinten, Teodor Sandu, Daniel Rodríguez Rivero, Thomas Grainger and 43 more
Reacted by marak.eth
Reacted by Joanna Falkowska, Patrick Moriarty, Ivancing, Nikolay Osaulenko, Anton Fedchenko, Peter Matta, bakirov.dev, Esteban Uscanga, Code Scratcher, IliaVolk and 4 more
Well, this can't be very complex to implement since you already have the infrastructure for type checking. At least you could expect to get injected type checking for primitive types when compiling with --debug, as mentioned in the other thread:
This has lead us to introduce type checks for all exported functions in TypeScript, although they really feel verbose in a typed language.
export function add(x: number, y: number): number {
if (typeof x !== 'number' || typeof y !== 'number') {
throw new TypeError('x and y need to be numbers');
}
return x + y;
}
If this does not match your design goals, maybe you should change them?
Reacted by Tanguy Krotoff, Steve Pikelny, Gabriel Elkind, Nateowami, John Weisz, Daniel Rodríguez Rivero, Joe Pea, Marco Quinten, Sunny Gonnabathula, Marco Scannadinari and 23 more
Reacted by Aluan Haddad, Han Seoul-Oh, B, Vesa Nikkilä and Keith Ito
Primitive TypeChecking is easy, and the results of doing it yourself guide type inference. If you expect to receive something other than the indicated type, perhaps you should not specify number.
I would expect to get a runtime error if a function receives eg a string instead of a number in runtime. That would really kill the flaws of working with JavaScript.
Don't get me wrong, I love TypeScript, but I really hate JavaScript..
Reacted by bodrin, Lorenzo Giuliani, Andr3w, gwltrs, Slavo Vojacek, stevenwdv and Nurbol Alpysbayev
Well I think that is mission impossible for me. JavaScript is great for what is was made for, but for large complex systems built and maintained by a team I can't see how it could be a good modern option.
jedmao Thank you, will have a look. But I still think it should be implemented in the TypeScript compiler (with a flag)
Ryan Cavanaugh (@RyanCavanaugh) it's been almost 2 years since this feature request was made and I'm wondering what it would take for the design goals to change or make an exception for this particular request? Now that the initial TypeScript roadmap is complete, perhaps we can entertain this idea?
I think this proposed compiler flag would only make sense in development and staging environments, but it would serve as a great tool for debugging the application at runtime.
Consider the scenario in which an API request is made and we expect the API response to adhere to a model (interface).
const__Foo={validate: (d)=>{if(typeofd.bar!=='string'){thrownewTypeError('Foo.bar should be a string.');}}};functionhandleResponse(data){Foo.validate(data);returndata;}handleResponse({bar: 'baz'});// OKhandleResponse({bar: 42});// TypeError('Foo.bar should be a string.');
Rather than getting some error about some foo prop being undefined, wouldn't it be more useful to know that the complex type that was defined as input didn't come back the way we expected?
Reacted by Andreas, Tanguy Krotoff, Prasanth Ullattil, Tate Barber, Owen Kelly, Tom Crockett, Sebastien A, Serge S. Gulin, Marco Quinten, Mauricio Navarro Miranda and 42 more
Anyway, will anyone support me if I'm going to implement this feature by forking this project?
(I will seriously implement this if I get more than 20 reactions)
WJH (@wongjiahau) I wouldn't necessarily want all "as" operators to create type checking code around it. I'd much rather be explicit with it with a simple ! on a case-by-case basis. Did you take a look at io-ts?
jedmao I did look at io-ts, I actually wanted to use it but it is not really natural when you have nested type.
Trent (@tbillington) Ok now I understand your concern (of the backwards-compatibility).
So, I guess the syntax should looks like this as suggested by jedmao?
functionsquare1(x: number!){// TS compiler will generate code that will assert the type is correctreturnx*x;}functionsquare2(x: number){// TS compiler will not generate any type-assertion codereturnx*x;}varapple: any="123";square1(apple);// Compiler will not throw error, since the type of `apple` is `any`. // But this code will cause error to be thrown at runtimesquare2(apple);// Compiler will throw error varbanana="123";square1(banana);// Compiler will generate error because you can't cast string to number by any means
So, the ! operator is actually suppressing error that is related to casting from any to specific type.
WJH (@wongjiahau) my opinion is that the compiler errors should be exactly as they are w/o change. The only difference is runtime. As such, I don't see how the ! operator would suppress any compiler errors at all.
Let's take your example:
functionsquare1(x: number!){// TS compiler will generate code that will assert the type is correctreturnx*x;}
The TS compiler would simply emit something akin to the following:
functionsquare(x){if(typeofx!=='number'){thrownewTypeError('Expected a number.');}returnx*x;}
Super easy with primitive types, but more complicated with interfaces and more complex types (but io-ts solves that issue).
I just wish it were built into the compiler itself so we didn't have to do all this extra stuff. But it really is complex and requires a lot of thought behind it in order to do it right.
Here's some other ideas I thought of recently:
// First line of fileconstx: number!=42;// compiler error: redundant type checking on a known type.
constx: number=42;consty: number!=x;// also redundant
constx: number=42;consty: string!=x;// compiler error: constz: string!=xasany;// OK, but should it be?
There's really a lot to think about here.
Reacted by WJH, Chet Corcos, Sladav and Jan Baykara
jedmao I understand what you say, but please allow me to clarify the error suppression with a typical example.
Suppose you have the following code (using express.js) :
interfaceFruit{name: string,isTasty: boolean}app.post("/uploadFruit",(req,res)=>{constnewFruit=req.body;// Note that `req.body` has type of `any`// This line shouldn't throw compile error because we already tell the compiler // to assert that newFruit is type of `Fruit` by adding the `!` operatorsaveFruit(newFruit);});functionsaveFruit(newFruit: Fruit!){// save the fruit into database}
If that line of saveFruit(newFruit) will throw compilation error, then this runtime typechecking feature would be meaningless already.
I hope you can understand what I'm trying to say.
Moreover, I think that syntax A will be better than syntax B
// syntax A constapple!: string="...";// syntax Bconstapple: string!="...";
This is because syntax A will be much more easier to be parsed, and it is also more consistent with the ?: operator.
WJH (@wongjiahau) I'm not suggesting that saveFruit(newFruit) should throw a compiler error, as req.body is of type any. Just like it won't throw a compiler error today, it shouldn't in the future. That's exactly what I said before. Current compiler errors should remain compiler errors, period.
That said, I still don't see where any error is being "suppressed" as you say.
I do kinda' like the !: operator idea. That would make forced union types a lot easier to read:
jedmao Sorry for the misunderstanding, because I thought the compiler will throw error if we cast from any to a specific type, just realized it won't throw error.
So, do you guys want to fork this project and implement this feature?
jedmao I'm actually thinking of forking it as another project (perhaps I'll call it Experimental-Typescript ? ).
Because I notice there are a lot of potential pull request and issues that will not be implemented in this project, I'm thinking of merging them and implementing them.
I see some people made libraries for runtime checking but I would show another one (created by myself): https://github.com/ThaFog/Safetify
Well i's not stricte for runtime type checking because the major difference comparing to others above is that it doesn't throw errors but simply replacing incorrect values with type-safe equivalents. So it's better to use in webservices, with taking data from API or so.
However I'm planning to add features like optional errors throwing, global onError callbacks, constraints, json or function resolvers. then it would be more for runtime checking
Activity
basarat commentedon Dec 30, 2014
Perhaps something more akin to google
AtScriptfor consistency. Basically flag--rttswill cause emited JS to havertts(runtime type system) checks inserted.jednano commentedon Dec 30, 2014
I'm suggesting, however, that you can optionally enable runtime type checking on some args and not others. Or, at least, skip type checking on private methods, optionally.
RyanCavanaugh commentedon Dec 30, 2014
This remains outside our design goals (https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals)
davidrapin commentedon May 11, 2016
For people like me coming here looking with high hopes, you might want to take a look at http://angular.github.io/assert/
jeansson commentedon Dec 7, 2016
Well, this can't be very complex to implement since you already have the infrastructure for type checking. At least you could expect to get injected type checking for primitive types when compiling with --debug, as mentioned in the other thread:
If this does not match your design goals, maybe you should change them?
aluanhaddad commentedon Dec 7, 2016
Primitive TypeChecking is easy, and the results of doing it yourself guide type inference. If you expect to receive something other than the indicated type, perhaps you should not specify
number.jeansson commentedon Dec 7, 2016
I would expect to get a runtime error if a function receives eg a string instead of a number in runtime. That would really kill the flaws of working with JavaScript.
Don't get me wrong, I love TypeScript, but I really hate JavaScript..
aluanhaddad commentedon Dec 7, 2016
But, IMO, you need to learn to love JavaScript to fully take advantage of TypeScript.
jednano commentedon Dec 7, 2016
Andreas (@jeansson) did you take a look at tcomb?
jeansson commentedon Dec 7, 2016
Well I think that is mission impossible for me. JavaScript is great for what is was made for, but for large complex systems built and maintained by a team I can't see how it could be a good modern option.
jedmao Thank you, will have a look. But I still think it should be implemented in the TypeScript compiler (with a flag)
jednano commentedon Dec 7, 2016
Ryan Cavanaugh (@RyanCavanaugh) it's been almost 2 years since this feature request was made and I'm wondering what it would take for the design goals to change or make an exception for this particular request? Now that the initial TypeScript roadmap is complete, perhaps we can entertain this idea?
I think this proposed compiler flag would only make sense in development and staging environments, but it would serve as a great tool for debugging the application at runtime.
Consider the scenario in which an API request is made and we expect the API response to adhere to a model (interface).
Compiles to:
Rather than getting some error about some
fooprop being undefined, wouldn't it be more useful to know that the complex type that was defined as input didn't come back the way we expected?68 remaining items
wongjiahau commentedon Apr 24, 2018
Anyway, will anyone support me if I'm going to implement this feature by forking this project?
(I will seriously implement this if I get more than 20 reactions)
tbillington commentedon Apr 24, 2018
Apologies, my example used a non-any type when you specified casting any -> non-any.
Still, it's a backwards-incompatible change which means you're fighting an uphill battle. That's why other people have suggested new syntax such as
!.jednano commentedon Apr 24, 2018
WJH (@wongjiahau) I wouldn't necessarily want all "as" operators to create type checking code around it. I'd much rather be explicit with it with a simple
!on a case-by-case basis. Did you take a look at io-ts?wongjiahau commentedon Apr 24, 2018
jedmao I did look at
io-ts, I actually wanted to use it but it is not really natural when you have nested type.Trent (@tbillington) Ok now I understand your concern (of the backwards-compatibility).
So, I guess the syntax should looks like this as suggested by jedmao?
So, the
!operator is actually suppressing error that is related to casting fromanyto specific type.jedmao Trent (@tbillington) What do you think?
jednano commentedon Apr 24, 2018
WJH (@wongjiahau) my opinion is that the compiler errors should be exactly as they are w/o change. The only difference is runtime. As such, I don't see how the
!operator would suppress any compiler errors at all.Let's take your example:
The TS compiler would simply emit something akin to the following:
Super easy with primitive types, but more complicated with interfaces and more complex types (but io-ts solves that issue).
I just wish it were built into the compiler itself so we didn't have to do all this extra stuff. But it really is complex and requires a lot of thought behind it in order to do it right.
Here's some other ideas I thought of recently:
There's really a lot to think about here.
wongjiahau commentedon Apr 24, 2018
jedmao I understand what you say, but please allow me to clarify the error suppression with a typical example.
Suppose you have the following code (using
express.js) :If that line of
saveFruit(newFruit)will throw compilation error, then this runtime typechecking feature would be meaningless already.I hope you can understand what I'm trying to say.
Moreover, I think that syntax A will be better than syntax B
This is because syntax A will be much more easier to be parsed, and it is also more consistent with the
?:operator.So you can read the
!:operator asmust be a.jednano commentedon Apr 24, 2018
WJH (@wongjiahau) I'm not suggesting that
saveFruit(newFruit)should throw a compiler error, asreq.bodyis of typeany. Just like it won't throw a compiler error today, it shouldn't in the future. That's exactly what I said before. Current compiler errors should remain compiler errors, period.That said, I still don't see where any error is being "suppressed" as you say.
I do kinda' like the
!:operator idea. That would make forced union types a lot easier to read:wongjiahau commentedon Apr 24, 2018
jedmao Sorry for the misunderstanding, because I thought the compiler will throw error if we cast from
anyto a specific type, just realized it won't throw error.So, do you guys want to fork this project and implement this feature?
jednano commentedon Apr 24, 2018
I think Microsoft would have to agree to accept a community PR for me to invest time in this. Also, I just don't have the bandwidth.
wongjiahau commentedon Apr 24, 2018
jedmao I'm actually thinking of forking it as another project (perhaps I'll call it Experimental-Typescript ? ).
Because I notice there are a lot of potential pull request and issues that will not be implemented in this project, I'm thinking of merging them and implementing them.
ccorcos commentedon Apr 24, 2018
Since we're talking a lot about validation of unsafe data, I think Phantom types are relevant:
https://medium.com/@gcanti/phantom-types-with-flow-828aff73232b
Currently, its not possible in Typescript.
lkster commentedon Apr 24, 2018
I see some people made libraries for runtime checking but I would show another one (created by myself):
https://github.com/ThaFog/Safetify
Well i's not stricte for runtime type checking because the major difference comparing to others above is that it doesn't throw errors but simply replacing incorrect values with type-safe equivalents. So it's better to use in webservices, with taking data from API or so.
However I'm planning to add features like optional errors throwing, global onError callbacks, constraints, json or function resolvers. then it would be more for runtime checking
Ciantic commentedon May 30, 2018
Creator of Node.js seems to be working on similar project for TypeScript: https://github.com/ry/deno "A secure TypeScript runtime on V8"
ccorcos commentedon May 31, 2018
Interesting. I checked out the repo -- still pretty unclear what it's for...