| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) pack this |
Sorry, something went wrong.
|
Heya Orta Therox (@orta), I've started to run the tarball bundle task on this PR at d69f2b0. You can monitor the build here. |
Sorry, something went wrong.
|
Hey Orta Therox (@orta), I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so: {
"devDependencies": {
"typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/84753/artifacts?artifactName=tgz&fileId=458CBB664D3CE9EFA165B438F01414D55349C27455F3F7CE2CC288A173FC410B02&fileName=/typescript-4.1.0-insiders.20200910.tgz"
}
}
and then running npm install. There is also a playground for this build. |
Sorry, something went wrong.
|
Idea: Find a way to "match" the error string into the typescript diagnostic object, to reuse the translation of diagnostic message. A possible solution: throw {diagnostic: "Did_you_mean_0", args: [T] }
That will match the Diagnostic.Did_you_mean_0 and therefore it will be automatically translated by the compiler. |
Sorry, something went wrong.
|
Idea: Find a way to emit other kinds of diagnostic, like suggestions or warning. If so, there should be another mechanism to offer a underlying type like throw {message: T, type: T2, kind: "suggestion"}
|
Sorry, something went wrong.
|
Oh I just realized we can throw a object type so it can include more details! Please help me to investigate the possibility of this to find a good shape of the error object. Possible properties:
|
Sorry, something went wrong.
| "category": "Error", | ||
| "code": 2793 | ||
| }, | ||
| "Type instantiated results in a throw type saying: {0}": { |
There was a problem hiding this comment.
Something shorter? Type instantiation threw. {0}?
Sorry, something went wrong.
|
Idea: Allow throw type to be handled by conditional type. This allows some error recovery or composing multiple errors. T extends throw infer E1 ?
U extends throw infer E2 ?
throw `\n ${E1}\n ${E2}`
: T : never |
Sorry, something went wrong.
import type { DiagnosticCategory } from 'typescript'
/**
* Since this is a type-level thing, any union in this type is considered invalid value
* cause their value is not determinate yet.
*
* `throw "string"` is convert to `throw { message: "string" }`
*/
type ErrorMessage = {
/**
* ! implemented !
* If diagnostic is not exist or not valid (key not found / not a tuple) this message will be used
*
* If it is not a string literal type, it will be formatted by `getTypeNameForErrorDisplay`
*/
message: any
/**
* What type should this throw type compatible(equal) with?
* Useful to "add" diagnostic message on a type and preserve itself
* @default never
*/
type?: any
/**
* ! implemented !
* TODO: provide completion for this in the language service
* Actually it is `[keyof Diagnostic (a @internal variable of ts), ...any[]]`
* @example ["_0_expected", T] results in "T expected" (with translation in different languages)
*/
diagnostic?: [type: string, ...args: any[]]
/**
* ! implemented !
* @default `Error` when undefined. `Message` when value is invalid.
*/
category?: 'suggestion' | 'error' | 'warning' | 'message'
/**
* It seems like deprecated is not in the DiagnosticCategory
*/
deprecated?: boolean
// ! Let developers custom the error code might not a good idea.
// code: number
/**
* When it happened on an identifer, replace the identifier with the suggestion
* e.g.: name => window.name
*
* When it happened on a type alias, do nothing
* When it happened on a CallExpression, do nothing
*
* ? Is this really useful cause the throw cannot get the original source text ?
*
* If we have higher kind types, this option can receive a un-instantiated generic type
* as a type-level function.
*
* @example
* type MyError<Context extends ...> = ...
* type T<U> = ... extends ... ? ... : throw {message: ..., suggestion: MyError}
*/
suggestion?: string
/**
* Let message be able to chain
*/
next?: ErrorMessage | ErrorMessage[]
} |
Sorry, something went wrong.
|
Sorry, something went wrong.
|
Sorry, something went wrong.
|
To be honest the initial idea is great - but adding diagnostics types and formatting feels like an overkill. It might even step into the linters world. The syntax is more complex too. I think having the ability to throw is already great as is. |
Sorry, something went wrong.
Hmm, I didn't introduce a new syntax for a "detailed" throw. It's a plain object literal type. I need some advice from the TypeScript team. If they think it's no need to do this, I'll stop working on that feature sets and focus on what will be accepted. Now I still have two complex ideas:
Is there anything I mentioned above that the TS team doesn't want? cc Ryan Cavanaugh (@RyanCavanaugh) Orta Therox (@orta) Wenlu Wang (@Kingwl) |
Sorry, something went wrong.
|
Should the playground link posted by TypeScript Bot (@typescript-bot) be able to run the examples in the PR description? I'm not able to see the error messages as in the screenshot |
Sorry, something went wrong.
|
Oh, I'm sorry it's a regression (bug) Tom Sherman (@tom-sherman) I'll fix it soon. You can try an old version https://www.staging-typescript.org/play?ts=4.1.0-pr-40402-15 (but it has other bugs) |
Sorry, something went wrong.
|
I'm excited to see that this is still being (somewhat) actively developed. As a library developer, I would absolutely love to see this land. Any idea how to get the necessary attention for this to move forward? |
Sorry, something went wrong.
|
It always excites me when you are looking for a feature and some devs have been working on it for years. Yes I would love a "throw" type because some type checks require extraneous chaining of type generics and it can be hard to deliver semantic reasoning |
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser) Is it possible to get a quick update on the team's plans for this PR? It has received a lot of interest and support from the community and been open for over 2 years now. The author recently stated:
While his diligence is admirable, he's kind of in a difficult spot having to continually make updates like this without any assurances as to when his work will be merged, if ever. Jack Works (@Jack-Works) Just wanted to thank you for continuing to maintain this for so long! |
Sorry, something went wrong.
|
Just pointing out that the https://github.com/mmkal/expect-type TS type-checking library could really benefit from this PR if merged. Jack Works (@Jack-Works) Thank you for creating this! Excited to hopefully use it! |
Sorry, something went wrong.
|
This is super nice. I have some questions - how (if) would the following constructs work? type T = throw "oops";
type U = "foo" | throw "oops";
type V = { a?: throw "oops" };
type W = (arg: throw "oops") => any;
type X<T> = T extends throw infer E ? true : false;Also, if I have type MakeThrow<T extends string> = throw T; can I use MakeThrow<"oops"> everywhere I could use throw T and it will work in the same way? Also, if throw X is just another type, how does it relate to other common types? For example, does it extend never, any, unknown? I would suggest making throw "something" extend (i.e. be a subtype of) never. In a way that never becomes the "union of all throw types". What does everyone think? I suspect having good answers to all these questions is a way to help the PR move forward. |
Sorry, something went wrong.
|
Pedro Augusto de Paula Barbosa (@papb) (rearranging your questions slightly)
If you look at the files changed in the PR, the tests show what the currently-proposed behavior is. That said, maybe Orta Therox (@orta) could ask the bot to set this up so that you could try them out in the playground? My understanding (of what at least I'd want) is that error T would give an immediate error (and resolve to never) and time T is an actual concrete type without any type variables.
I would hope all of these would immediately error.
This seems maybe problematic. I can see some value to being able to introspect the errors (particularly for library API testing), but I'd be inclined to move forward without it and really just make it an exact never after issuing the diagnostic. If there's a compelling use for this, it could be done in a future iteration.
I would hope so. In MakeThrow's definition, you're throwing a type variable, so it shouldn't error yet. But once you instantiate that type with a concrete string, then it can produce an actual diagnostic.
TypeScript already treats type mismatches in a particular way, e.g. if you write declare function foo<T>(arg1: T, arg2: T): T then foo(42, 'x'); will produce a diagnostic, but type checking will continue with treating the erroneous expression as if were any. This feature should be consistent with that.
I don't think "subtype of never" is really a concept we want to open up here. The whole point of never is that it's a subtype of everything, so I think "there be dragons". |
Sorry, something went wrong.
i'd assume that's intended to behave as a type level try-catch (of course, definitely a good idea to figure out how useful it would actually be in practice) |
Sorry, something went wrong.
|
Just wanted to bump this up. |
Sorry, something went wrong.
|
My thought is that by the time there's something to "catch", it's already too late - the error has been emitted. Using throw for this is potentially nice because it's been a JS keyword forever, so it's unlikely to clobber any actual existing names. But I dislike any analogy it might make what would suggest to anyone that they can catch it to suppress any error, or really do any sort of logic. Just emit the error and bail out with a never. |
Sorry, something went wrong.
|
Agree that catching it in typing doesn't make sense. It's a little surprising for me to think about it being recoverable in conjunction with a @ts-ignore. I want to say that @ts-ignore generally resolves weird things to any rather than never. So maybe it would make sense for throw to resolve to an any? If not suppressed, it would just stop compiling anyways. |
Sorry, something went wrong.
|
close for housekeeping. I still have interest in this feature, so I will re-open and rebase it if the TS team also has an interest in it and give some suggestions of its type behavior. thanks for everyone watching & testing this PR! |
Sorry, something went wrong.
|
Jack Works (@Jack-Works) Your work is very much appreciated! Wanted to take the chance to underscore that since this PR was created in 2020, the most popular libraries in the ecosystem have invested even further in advanced TS features to create the rich DX many devs have come to expect. Generics that perform some kind of input validation are a common manifestation of this trend, and unfortunately, most library authors end up resorting to TS's builtin solution, never, which is totally opaque when it comes to helping end users resolve the underlying problem. While some libraries like ArkType have started returning custom error messages instead, the problems I mentioned in my original comment still apply, and the fact that it feels like a hack likely deters a lot of authors from returning anything other than never. If there is something about this solution in particular that is unsatisfactory, it would be really useful to at least have an idea of what it is so that going forward contributors can avoid repeating it. I can't help but feel a bit sad seeing high-quality contributions like this languish. Everyone involved would greatly benefit from even a very brief explanation of the team's stance. |
Sorry, something went wrong.
|
Damn, this is a travesty :/ |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Fixes #23689
Playground: https://www.staging-typescript.org/play?ts=4.2.0-pr-40468-44
This PR introduces:
Considered use cases:
Welcome to suggest more use cases!
TypeAlias instantation
Prevent CallExpression
Prevent use of identifiers