ts-loader: vscode language service type check succeeded. But the webpack build showed error and emitted file worked fine.

Environment

Window 10
"ts-loader": "^4.5.0",
"typescript": "^3.0.1",
"webpack": "^4.17.1",

What am I doing

I wrote the script part of the .vue file in a separate .ts file. (Because vue’s language service is not perfect) I am trying to make the .vue component have the correct type. I came up with the following two methods:

Method A

By tricking the vscode language service, the imported file for vscode is *.ts, but the imported file for webpack is *.vue. For example:

// webpack config. Allow vue extensions to be omitted
resolve: {
    extensions: ['.vue', '.js', '.jsx', '.mjs', '.ts', '.tsx'],
}

// file list
Hello.vue
Hello.ts

// use Hello.vue
import Hello from './Hello';

Method B

Define a type for a .vue file using a .d.ts file. For example

// file list
World.ts
World.vue
World.vue.d.ts

// .d.ts content
export { default } from './World';

Expected Behaviour

Webpack builds successfully and does not output errors.

Actual Behaviour

Method A

ERROR in D:\issue-ts-loader-20180829\src\component\App.ts
[tsl] ERROR in D:\issue-ts-loader-20180829\src\component\App.ts(4,19)
      TS2307: Cannot find module './Hello'.

Method B

ERROR in D:\issue-ts-loader-20180829\src\component\App.ts
[tsl] ERROR in D:\issue-ts-loader-20180829\src\component\App.ts(17,23)
      TS2339: Property 'world' does not exist on type 'Vue'.

Steps to Reproduce the Problem

Method A

In App.ts, comment line 2 and uncomment line 3. https://github.com/ZSkycat/issue-ts-loader-20180829/blob/master/src/component/App.ts#L2-L3

Method B

In App.ts, uncomment line 15. https://github.com/ZSkycat/issue-ts-loader-20180829/blob/master/src/component/App.ts#L15

Location of a Minimal Repository that Demonstrates the Issue.

https://github.com/ZSkycat/issue-ts-loader-20180829 available commands:

npm start
npm run build

I have debugged enhanced-resolve, webpackConfig.resolve.extensions works fine. I also tried to debug ts-loader, but I don’t know about typescript api, so I can’t find the reason. Sorry, I am not good at English. And I want to get help.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (9 by maintainers)

Most upvoted comments

@HerringtonDarkholme I found a more appropriate method, thank you for reminding me.

We only need to spoof the IDE’s language service to achieve the goal. For example:

Demonstrates Repository: https://github.com/ZSkycat/issue-ts-loader-20180829/tree/better

Hello.vue

<template>
    <div><h1>Hello</h1></div>
</template>

<script src="./Hello.vue.ts"></script>

Hello.vue.ts

import { Component, Vue } from 'vue-property-decorator';

@Component<Hello>({
    name: 'Hello',
})
export default class Hello extends Vue {
    hello() {
        console.log('hello!');
    }
}

Used in ts file

import Hello from './Hello.vue';

The most important thing is the naming of the ts file.

  • For vscode, ‘./Hello.vue’ points to ‘./Hello.vue.ts’
  • For webpack, ‘./Hello.vue’ points to ‘./Hello.vue’ and does not trigger type checking errors