TypeScript Version: 2.1.1
Code
import * as webpack from 'webpack';
export default: webpack.Configuration {
};
Expected behavior:
No error
Actual behavior:
[ts] Expression expected.
error at default:
I couldn't find an issue for this but it's very likely it's a duplicate
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 https://github.com/Microsoft/TypeScript/issues/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 PropertyDecorator
type in lib.d.ts
, I can't write it easily. I have to use a function expression.
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:
TypeError: controller.default is not a function
at fs_1.readdirSync.filter.forEach.Promise.resolve.then.then.controller (/Users/bbendavi/Documents/cdt-box/dist/server/config/routes.js:16:71)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:160:7)
at Function.Module.runMain (module.js:703:11)
at startup (bootstrap_node.js:193:16)
at bootstrap_node.js:617:3
I asked this on SO with a full file examples:
https://stackoverflow.com/questions/48696327/how-to-define-a-module-default-export-type-in-typescript
Would much appreciate your help!
import * as webpack from 'webpack'
export default {
...
} as webpack.Configuration
@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 @typescript-eslint/recommended
.
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 as
.
e.g.
export default ((req, res) => {
// Intellisense Enabled on `req` & `res`!
return 'Hello World!';
}) as RequestHandler;
🚩Edit for downvoters: Typescript does check functions for return type & parameter compatibility when typecasting. Unlike typecasting for object types, functions retain a degree of type safety.
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 export const default :Type = value;
export type default = Type;
export interface default {}
could bring us more uniformity, avoid to introduce a new set of grammars just for default?
Most helpful comment
Yes, that's what I do know but I wish I didn't have to.