ts-loader icon indicating copy to clipboard operation
ts-loader copied to clipboard

TS2322: Type 'number' is not assignable to type 'SSRSlot'

Open michaelcozzolino opened this issue 2 years ago • 2 comments

Expected Behaviour

The error in the pic should not be shown.

Actual Behaviour

when using dynamic slot with v-for with vue components, i'm getting the following errors:

error in /home/michael/Development/app/symfony-demo-vue-bug/assets/vue/components/Parent.vue.ts 8:00:25 AM

[tsl] ERROR in /home/michael/Development/app/symfony-demo-vue-bug/assets/vue/components/Parent.vue.ts(5,93) TS2322: Type 'number' is not assignable to type 'SSRSlot'.

error in /home/michael/Development/app/symfony-demo-vue-bug/assets/vue/components/Parent.vue.ts 8:00:25 AM

[tsl] ERROR in /home/michael/Development/app/symfony-demo-vue-bug/assets/vue/components/Parent.vue.ts(6,37) TS2769: No overload matches this call. The last overload gave the following error. Argument of type '<K extends string | number | symbol>(slotName: any) => { name: any; fn: Function; }' is not assignable to parameter of type '<K extends string | number | symbol>(value: any, key: K, index: number) => VNodeChild'. Type '{ name: any; fn: Function; }' is not assignable to type 'VNodeChild'. ` image

I tried to create a vue app with the same components without webpack and it compiles without errors.

Steps to Reproduce the Problem

steps to reproduce:

  1. git clone https://github.com/michaelcozzolino/symfony-demo-vue-bug
  2. composer install
  3. yarn install
  4. yarn watch or yarn build
  5. observe the errors
  6. php -S localhost:8000 -t public/

The components are in assets/vue/components and the purpose of them is to show a list of names by using dynamic slot names. by going to http://localhost:8000/en/blog/ the names are shown correctly.

Location of a Minimal Repository that Demonstrates the Issue.

https://github.com/michaelcozzolino/symfony-demo-vue-bug

michaelcozzolino avatar Mar 15 '23 20:03 michaelcozzolino

I had the same problem and I tried to solve it by setting the transpileOnly option (see https://github.com/inertiajs/inertia/issues/1070#issuecomment-1084826500), but it didn't work.

The working solution for me was using the fork-ts-checker-webpack-plugin in webpack.mix.js, just like suggested here.

This is how my webpack.mix.js looks like now:

const mix = require('laravel-mix');

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

mix.webpackConfig({
	module: {
		rules: [
			{
				test: /\.tsx?$/,
				loader: 'ts-loader',
				exclude: /node_modules/,
			},
		],
	},
	plugins: [new ForkTsCheckerWebpackPlugin()],
	resolve: {
		extensions: ['.*', '.js', '.jsx', '.vue', '.ts', '.tsx'],
	},
})
	.setPublicPath('./webroot')
	.options({ processCssUrls: true });

mix.js('resources/js/foo.js', 'webroot/js/AssetMix')
	.ts('resources/js/bar/src/main.ts', 'webroot/js/AssetMix/bar.js')
	.vue({ version: 3 })
	.version();

if (!mix.inProduction()) {
	mix.sourceMaps();
}

antogno avatar Sep 19 '23 09:09 antogno

Thanks a lot for your response @antogno. The fork-ts-checker-webpack-plugin also worked for me. I was a little concerned at first because your configuration example is a little daunting. However, the Webpack plugin was key to getting it working.

The implementation was actually more straightforward than I expected, at least for Webpack >5.92.x:

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
/* or */
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';

/* then */
export default function() {
 return {
   ...
   plugins: [new ForkTsCheckerWebpackPlugin()],
   module: {
     rules: [
       {
         test: /\.ts$/,
         loader: 'ts-loader'
       }
     ]
   }
   ...
 }
}

The configuration example in their readme is good if you're not using ESM.

l00sed avatar Jul 30 '24 14:07 l00sed