-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Type annotations for default export #13626
Comments
Would not this be sufficient? const config: webpack.Configuration = {
}
export default config; |
Yes, that's what I do know but I wish I didn't have to. |
related to #3792. we have tried to keep the module export as simple as possible on the syntax side. |
I think it's a little more related to to the following scenario regarding function declarations. if I want to write a decorator that is verified against the export let Encrypt: PropertyDecorator = function (obj, propName) {
}; which is case of friction whenever I want to actually implement a decorator without making a mistake. |
I am trying to use a default export in the following way readdirSync(join(__dirname, "../controllers/box"))
.filter(f => f !== "*.spec.ts")
.forEach(controllerFile => {
const controllerBaseName = basename(controllerFile, ".js")
import(`../controllers/box/${controllerBaseName}`).then((controller)=>{
appRouter.use(
`/box/${controllerBaseName}`, controller.default(boxServiceAccountClient))
}).catch(error=>{
console.log(error)
})
}); //end forEach I get an error:
I asked this on SO with a full file examples: Would much appreciate your help! |
|
@IgorGee That's the proper way of doing it IMHO |
The problem with export default ... as X is that it's a cast, so it purposely loses type safety. |
@pelotom As a general matter of fact, you're completely right, I'd avoid putting this in my codebase. For the scope of this thread where this is about webpack configuration, I think we're just fine |
@jlouazel leaving aside whether type safety is any less important in a webpack config... the issue is not specific to webpack, it's about annotating the type of the default export in general. |
@IgorGee That's forbidden in |
const as = <T>(value: T) => value
export default as<webpack.Configuration>({
// ...
}) |
Would love to see this feature for nice succinct code |
If you're exporting a function, put it in parenthesis before the export default ((req, res) => {
// Intellisense Enabled on `req` & `res`!
return 'Hello World!';
}) as RequestHandler;
|
I have the same problem too. Need to type default export instead of cast. |
could also use an iife so that the type is at the beginning of the export rather than the end export default ((): MyType => ({
k: v
})(); |
While this gives me type hints inside the function (thanks @mccallofthewild ) export default (({ withIcon, children }) => {
return <SomeJSX withIcon={withIcon}>{children}</SomeJSX>
}) as React.FC<{withIcon: boolean}> I would still prefer to have the type declared up front (not sure about the syntax here though) export default: React.FC<{withIcon: boolean}> (({ withIcon, children }) => {
return <SomeJSX withIcon={withIcon}>{children}</SomeJSX>
}) |
Maybe |
The solution proposed by @IgorGee works but is not fully reliable for type checking. My default export is a If I try with a typed constant (the actual only solution): const resourceProps: ResourceProps = {};
export default resourceProps; I will have:
But nothing if I do it like this: export default {} as ResourceProps; This make things harder to debug if something goes wrong because of this missing property. And we are using Typescript for that, right? :-) However, I also understand the need to type the default export. On some cases, we just return a configuration object like that: const resourceProps: ResourceProps = {
name:"users",
icon: UserIcon,
list: UserList,
create: UserCreate,
edit: UserEdit,
options:{
label: 'Utilisateurs',
},
};
export default resourceProps; It's a bit cumbersome to be forced to declare a new variable just to take benefit of typing. That was my two cents. I wanted to illustrate with some samples because I was myself a bit confused as a TypeScript beginner when I saw the lot of down votes on the previous solutions. |
what about: Edited: no a good solution, it's a reverse assertion, it's even worst than |
|
I am confusing about this too. any suggestion about typing the default export function? |
Currently you have to put it into a const first, then export it:
This issue is tracking a request to implement some way to avoid the extra repetition. |
The use case I'm looking at for this is to type and name a function that's a default export, without repeating the function name:
|
@ackvf's syntax suggestion seems like the best proposed so far.
Would that be difficult to implement? export default: {type} {value} |
I guess another option could be to allow "default" as a variable name to export.
|
This is type checked: import type { Config } from "package";
export default (): Config => {
return {
properties: true
};
}; |
@NikolaRHristov Yes, but this works only if you export a function, you are typing its return type. |
Re: #13626 (comment) I think this works well enough with type MyType = { name: string }
export default { name: 5 } satisfies MyType;
// Type 'number' is not assignable to type 'string'.(2322)
export default { name: "world", foo: 4 } satisfies MyType;
// Object literal may only specify known properties, and 'foo' does not exist in type 'MyType'.(1360)
export default { name: "world" } satisfies MyType;
// OK |
Will
|
type RequestHandler = (req: string, res: number) => string;
export default ((req, res) => {
return 1;
}) as RequestHandler;
// Conversion of type '(req: string, res: number) => number' to type 'RequestHandler' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
// Type 'number' is not comparable to type 'string'.(2352)
// and the whole block is highlighted as error.
export default ((req, res) => {
return 1;
}) satisfies RequestHandler;
// Type '(req: string, res: number) => number' does not satisfy the expected type 'RequestHandler'.
// Type 'number' is not assignable to type 'string'.(1360)
// but "RequestHandler" is highlighted as error (I would expect the return value to be highlighted). |
I think that |
@sid Vishnoi It works on function declarations too. export default (function (req, res) {
return 1;
}) satisfies RequestHandler; |
Just want to point out that using both type Union = { v: 1 | 2 }
export default { v: 1 } satisfies Union as Union; // Checked against Union and Union is preserved as the type of the export. Thanks to @acutmore for suggesting this use of |
Another workaround is to pass the export value to an identity function to check its value: function verify<T>(t: T): T { return t }
export default verify<React.FC<IProps>>(function(props) {
// ...
}) I'm not sure if there's a canonical identity function that'd avoid introducing your own. |
For now, we continue to
|
Oh, too bad. I thought an earlier commenter said that it did type it. We haven't upgraded to the version of typescript with this yet, but this was one thing I was looking forward to. |
You can also declare a typed variable and assign it in your export. type Union = { v: 1 | 2 };
let d: Union;
export default d = {
v: 1,
}; |
@mccallofthewild Then it could be reassigned. |
@mon-jai No. 😁 That's not how assignment works. let a;
let b = a = 1;
a = 2;
console.log(b == a);
// `false` |
Shouldn't the following code work? // d.js
let d: number;
export default d = 1:
// Other files
import d from "d.js";
d = 2; |
and even if it did work, I'm repeating my type declaration twice. Doing |
from 2017 -> 2024... Still this issue is open. wow. |
@MrBns Some time ago, @RyanCavanaugh proposed an initiative to deal with persistent issues - #54923. |
@a-tarasyuk unfortunately, in the announcement of that initiative they include:
I don't see anything indicating that has changed, but it's possible I missed it With that being said, if this issue is considered for a Feature Update, whoever is considering it, please note that #56235 (comment) ( |
TypeScript Version: 2.1.1
Code
Expected behavior:
No error
Actual behavior:
[ts] Expression expected.
error atdefault:
I couldn't find an issue for this but it's very likely it's a duplicate
Please 👍 on this issue if you want to see this feature in TypeScript and avoid adding "me too" comments. Thank you!
The text was updated successfully, but these errors were encountered: