no-string-based-x rules throw errors in Vue SFC
jwhitmarsh opened this issue · 7 comments
Bug Report
tslint-microsoft-contrib
version: 6.1.1- TSLint version: 5.16.0
- TypeScript version: 3.4.3
- Running TSLint via: Vue CLI generated webpack config, which I think uses fork-ts-checker-webpack-plugin
TypeScript code being linted
<template>
<div class="test">
{{ msg }}
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component
export default class TestComponent extends Vue {
msg = 'test'
}
</script>
with tslint.json
configuration:
{
"defaultSeverity": "warning",
"extends": ["tslint:latest", "tslint-microsoft-contrib/recommended"],
"linterOptions": {
"exclude": ["node_modules/**"]
},
"rules": {
"quotemark": [true, "single"],
"indent": [true, "spaces", 2],
"interface-name": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"no-consecutive-blank-lines": false,
"max-line-length": [
true,
{
"ignore-pattern": "'(.*?)'"
}
],
"arrow-parens": false,
"no-default-import": false,
"match-default-export-name": false,
"no-implicit-dependencies": [true, ["@"]],
"completed-docs": false,
"newline-per-chained-call": false,
"typedef": false,
"strict-boolean-expressions": false,
"no-unsafe-any": false,
"member-ordering": false,
"no-default-export": false,
"no-any": false,
"no-submodule-imports": false,
"no-this-assignment": false,
"member-access": false,
"trailing-comma": [true, "always"],
"no-relative-imports": [true, "allow-siblings"],
"prefer-type-cast": false,
"import-name": false,
"export-name": false,
"prefer-array-literal": false,
"no-suspicious-comment": false,
"no-inner-html": false,
"no-single-line-block-comment": false,
"no-backbone-get-set-outside-model": false,
}
}
Actual behavior
The 'no-string-based-set-timeout' rule threw an error in '/Users/jwhitmarsh/src/example/src/Test.vue':
TypeError: Cannot read property 'flags' of undefined
at tryGetDeclaredTypeOfSymbol (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:36600:24)
at getDeclaredTypeOfSymbol (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:36597:20)
at tryGetThisTypeAt (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:46543:99)
at checkThisExpression (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:46492:24)
at checkExpressionWorker (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:52215:28)
at checkExpression (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:52185:42)
at checkNonNullExpression (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:48560:37)
at checkPropertyAccessExpressionOrQualifiedName (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:48593:28)
at checkPropertyAccessExpression (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:48586:20)
at checkExpressionWorker (/Users/jwhitmarsh/src/example/node_modules/typescript/lib/typescript.js:52242:28)
Expected behavior
Not to throw an error
Indeed. Sadly, this is a duplicate of palantir/tslint#2099 and there's nothing we can really do here 😢
@jwhitmarsh I've tried your example and config with latest @vue/cli
and wasn't able to reproduce your error. Only error I've got was missing semicolon. And looks like no-string-based-set-timeout
works fine:
$ npm run lint
> tslint-test@0.1.0 lint C:\web\test\vue-tslint-test\tslint-test
> vue-cli-service lint
C:/web/test/vue-tslint-test/tslint-test/src/components/Test.vue
Forbidden setTimeout string parameter: 'console.log("hello");' (no-string-based-set-timeout)
8 | import { Vue, Component } from 'vue-property-decorator';
9 |
> 10 | setTimeout('console.log("hello");', 1000);
11 |
12 | @Component
13 | export default class TestComponent extends Vue {
Could you try to update typescript
or may be @vue/cli
.
If you still ahve problem reproduced - could you please create git repo with minimal reproduce case and share link here? Will reopen this issue if will be able to reproduce.
@IllusionMH Good spot, sorry I didn't test a new project, only existing code.
I've replicated it here https://github.com/jwhitmarsh/test-vue. It looks like calling this.$router
or this.$data
in one of the methods of an SFC causes it, so I don't know if that's because of the $
symbol causing issues with the parser?
EDIT: I should add, that is a recently created new project, so it is using typescript@3.4.5
and @vue/cli@3.7.0
.
Thanks for the repro. Was able to see exception in console and will investigate this one.
However I still think that this is most likely External issue.
@jwhitmarsh I've checked this issue and looks like root cause is caused by external factors.
TS isn't able to create symbol for class (when checks this
). If I rename file to .ts
and leave only content of script tag - rule is able to retrieve type info for class without any problems.
Therefore root cause of this issue should be fixed in intermediate steps that enables TS & TSLint to work with .vue
files.
As for this rules - it is only possible to mitigate negative impact of this exception - catch it and use simplified fallback logic. This is the way no-cookies
rule currently behaves.
@jwhitmarsh 6.2.0-beta
was published to npm. Could you please try install tslint-microsoft-contrib@beta
and check if issue is fixed for your actual code.
I've checked with your repro case and it works as expected - uses same logic as when typechecker is not available if encounter exception.
6.2.0
on Wednesday if no blockers.
LGTM! Thanks everyone, really appreciate it!