Suggestion
In userland code, you can use as const, but as a library author, I often want to provide the best possible experience, and when there's an opportunity for a literal value to be produced, I would like to infer that value for my users without them having to use (or remember to use) as const.
🔍 Search Terms
constant literals, Math.random, require as const, infer literals, readonly by default
✅ Viability Checklist
My suggestion meets these guidelines:
⭐ Suggestion
Provide an ability to narrow types at the type level (i.e. without JavaScript where you can use as const).
📃 Motivating Example
const notLiteral = () => "A";
A type like this produces () => string. I can improve the situation by specifying as const, which will cause it to produce () => "A".
Note: I'm not totally sure how related this is, but I've seen > () => Math.random() > 0.5 ? "A" : "B" which produces () => "A" | "B", and it's not clear to me what the difference is from the example above
However, in the context of a library, a library author doesn't have the option to do this in the type level. Something for this use-case would be a nice improvement:
////// LIBRARY CODE
const UploadThingServerHelper = <ValidRoutes,>(
route: {
readonly [Route in keyof ValidRoutes]: {
middleware: () => ValidRoutes[Route]; // how can a library author force a more specific type here?
onUpload: (response: { metadata: ValidRoutes[Route] }) => void;
};
}
) => {};
////// END USER CODE
const FileRouter = UploadThingServerHelper({
example: {
middleware: () => "someValue", // and end-user must remember to put `as const` here to force it to return a literal
onUpload: response => {
response.metadata; // the result is that the type here is not as narrow as it could be for the best user experience
// ^?
},
},
});
💻 Use Cases
This is useful for libraries trying to provide a great user experience with great inferencing. It should be a backwards compatible change. There are no workarounds that I'm aware of (from the code of a library).
Suggestion
In userland code, you can use
as const, but as a library author, I often want to provide the best possible experience, and when there's an opportunity for a literal value to be produced, I would like to infer that value for my users without them having to use (or remember to use)as const.🔍 Search Terms
constant literals, Math.random, require as const, infer literals, readonly by default
✅ Viability Checklist
My suggestion meets these guidelines:
⭐ Suggestion
Provide an ability to narrow types at the type level (i.e. without JavaScript where you can use
as const).📃 Motivating Example
A type like this produces
() => string. I can improve the situation by specifyingas const, which will cause it to produce() => "A".However, in the context of a library, a library author doesn't have the option to do this in the type level. Something for this use-case would be a nice improvement:
💻 Use Cases
This is useful for libraries trying to provide a great user experience with great inferencing. It should be a backwards compatible change. There are no workarounds that I'm aware of (from the code of a library).