@@ -53,9 +53,17 @@ module.exports = {
5353 } ,
5454 ] ,
5555
56+ /**
57+ Flag to let us correctly handle the case where we are running against a
58+ version of Ember CLI which does not support TS-based emit, and where we
59+ therefore *must* not emit a `defaultExport` local which includes a type
60+ parameter in the exported function call or class definition.
61+ */
62+ _isUsingTS : false ,
63+
5664 init ( ) {
5765 this . _super && this . _super . init . apply ( this , arguments ) ;
58- maybePolyfillTypeScriptBlueprints ( this ) ;
66+ this . _isUsingTS = maybePolyfillTypeScriptBlueprints ( this ) ;
5967 let isOctane = has ( 'octane' ) ;
6068
6169 this . availableOptions . forEach ( ( option ) => {
@@ -227,15 +235,8 @@ module.exports = {
227235 } ,
228236
229237 locals ( options ) {
230- let sanitizedModuleName = options . entity . name . replace ( / \/ / g, '-' ) ;
231- let classifiedModuleName = stringUtil . classify ( sanitizedModuleName ) ;
232-
233- let templatePath = '' ;
234- let importComponent = '' ;
235- let importTemplate = '' ;
236- let defaultExport = '' ;
237-
238238 // if we're in an addon, build import statement
239+ let templatePath = '' ;
239240 if ( options . project . isEmberCLIAddon ( ) || ( options . inRepoAddon && ! options . inDummy ) ) {
240241 if ( options . pod ) {
241242 templatePath = './template' ;
@@ -251,6 +252,14 @@ module.exports = {
251252 ? options . componentClass
252253 : '@ember/component' ;
253254
255+ let sanitizedModuleName = options . entity . name . replace ( / \/ / g, '-' ) ;
256+ let classifiedModuleName = stringUtil . classify ( sanitizedModuleName ) ;
257+
258+ let importComponent = '' ;
259+ let importTemplate = '' ;
260+ let defaultExport = '' ;
261+ let componentSignature = '' ;
262+
254263 switch ( componentClass ) {
255264 case '@ember/component' :
256265 importComponent = `import Component from '@ember/component';` ;
@@ -263,20 +272,53 @@ module.exports = {
263272 break ;
264273 case '@glimmer/component' :
265274 importComponent = `import Component from '@glimmer/component';` ;
266- defaultExport = `class ${ classifiedModuleName } Component extends Component {}` ;
275+ if ( this . _isUsingTS ) {
276+ componentSignature = signatureFor ( classifiedModuleName ) ;
277+ defaultExport = `class ${ classifiedModuleName } Component extends Component<${ classifiedModuleName } Signature> {}` ;
278+ } else {
279+ defaultExport = `class ${ classifiedModuleName } Component extends Component {}` ;
280+ }
267281 break ;
268282 case '@ember/component/template-only' :
269283 importComponent = `import templateOnly from '@ember/component/template-only';` ;
270- defaultExport = `templateOnly();` ;
284+ if ( this . _isUsingTS ) {
285+ componentSignature = signatureFor ( classifiedModuleName ) ;
286+ defaultExport = `templateOnly<${ classifiedModuleName } Signature>();` ;
287+ } else {
288+ defaultExport = `templateOnly();` ;
289+ }
271290 break ;
272291 }
273292
274293 return {
275294 importTemplate,
276295 importComponent,
296+ componentSignature,
277297 defaultExport,
278298 path : getPathOption ( options ) ,
279299 componentClass : options . componentClass ,
280300 } ;
281301 } ,
282302} ;
303+
304+ function signatureFor ( classifiedModuleName ) {
305+ let args = ` // The arguments accepted by the component${ EOL } Args: {};` ;
306+
307+ let blocks =
308+ ` // Any blocks yielded by the component${ EOL } ` +
309+ ` Blocks: {${ EOL } ` +
310+ ` default: []${ EOL } ` +
311+ ` };` ;
312+
313+ let element =
314+ ` // The element to which \`...attributes\` is applied in the component template${ EOL } ` +
315+ ` Element: null;` ;
316+
317+ return (
318+ `interface ${ classifiedModuleName } Signature {${ EOL } ` +
319+ `${ args } ${ EOL } ` +
320+ `${ blocks } ${ EOL } ` +
321+ `${ element } ${ EOL } ` +
322+ `}${ EOL } `
323+ ) ;
324+ }
0 commit comments