某一部分特性在 vue 文件里还能用上一点,比如类型约束,IDE 做类型推断也还行。
但是会有些其他的特性用不了, 比如我遇到这这俩问题。
一个是接口不能直接在 type='ts' 的 script 块中定义。(试了下类也一样)
还有就是无法使用类型断言。
在 .ts 文件里就能用, 在 vue 里就不能用。 你说像是接口这种就算了, 定义在 ts 文件里引进来我还能拿着用 (?其实这也很怪)。 像这种需要做类型断言的地方我就真的是没办法了...
Unexpected reserved word 'interface' (6:4) 4 | import {NotesView} from '@/api/uinfo-service'; 5 | > 6 | interface Ass { | ^ 7 | asv: string 8 | } 9 |
Unexpected token, expected "," (10:29) 8 | props: { 9 | note: { > 10 | type: Object as PropType<NotesView>, | ^ 11 | required: true 12 | } 13 | },
搜遍了各个地方, 没找到相似的例子。我甚至不知道是什么地方出的问题。 版本?插件?配置?
没办法只能来这求助啦
下边贴几个文件, 大佬们帮看下呗
package.json
{ "name": "fev-test", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint" }, "dependencies": { "@ant-design/icons-vue": "^6.0.1", "ant-design-vue": "^2.0.0", "axios": "^0.21.1", "babel-plugin-import": "^1.13.3", "compression-webpack-plugin": "^7.1.2", "core-js": "^3.8.3", "script-ext-html-webpack-plugin": "^2.1.5", "vue": "^3.0.5", "vue-class-component": "^8.0.0-rc.1", "vue-loader": "^15.9.6", "vue-loader-v16": "^16.0.0-beta.5.4", "vue-router": "^4.0.3", "vuex": "^4.0.0" }, "devDependencies": { "@types/chai": "^4.2.11", "@types/lodash": "^4.14.161", "@types/mocha": "^5.2.4", "@typescript-eslint/eslint-plugin": "^4.15.0", "@typescript-eslint/parser": "^4.15.0", "@vue/cli-plugin-babel": "~4.5.11", "@vue/cli-plugin-eslint": "~4.5.11", "@vue/cli-plugin-router": "~4.5.11", "@vue/cli-plugin-typescript": "~4.5.11", "@vue/cli-plugin-vuex": "~4.5.11", "@vue/cli-service": "~4.5.11", "@vue/compiler-sfc": "^3.0.5", "@vue/eslint-config-prettier": "^6.0.0", "@vue/eslint-config-typescript": "^7.0.0", "babel-eslint": "^10.1.0", "eslint": "^7.20.0", "eslint-plugin-html": "^6.1.1", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-vue": "^7.6.0", "less": "^4.1.1", "less-loader": "^7.3.0", "prettier": "^2.2.1", "style-resources-loader": "^1.4.1", "typescript": "~4.1.5", "vue-cli-plugin-style-resources-loader": "~0.1.4", "webpack-bundle-analyzer": "^4.4.0" }, "browserslist": [ "> 1%", "last 2 versions", "not dead" ] }
tsconfig.json
{ "compilerOptions": { "target": "esnext", "module": "esnext", "strict": true, "declaration": true, "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", "experimentalDecorators": true, "skipLibCheck": false, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "suppressImplicitAnyIndexErrors": true, "sourceMap": false, "baseUrl": ".", "rootDir": ".", "types": [ "webpack-env", "chai", "mocha" ], "paths": { "@/*": [ "src/*" ] }, "lib": [ "esnext", "dom", "dom.iterable", "scripthost" ] }, "exclude": [ "node_modules", "dist" ] }
babel.config.js
module.exports = { presets: ['@vue/cli-plugin-babel/preset'] };
.eslintrc.js
module.exports = { root: true, parserOptions: { parser: '@typescript-eslint/parser', }, env: { browser: true, es6: true, node: true, }, plugins: ['vue', '@typescript-eslint/eslint-plugin'], rules: { 'no-unused-vars': 'off', '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/member-delimiter-style': 'off', '@typescript-eslint/ban-ts-ignore': 'off', '@typescript-eslint/class-name-casing': 'off', 'vue/valid-v-slot': 'off', 'vue/experimental-script-setup-vars': 'off', 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', indent: ['off', 4, {SwitchCase: 1}], // 缩进不管 'line-comment-position': [ 'off', {position: 'above', ignorePattern: 'ETC'}, ], // 强制行注释的位置 'vue/no-v-model-argument': 'off', 'vue/no-setup-props-destructure': 'off', 'vue/no-multiple-template-root': 'off', '@typescript-eslint/no-var-requires': 0, 'vue/html-indent': ['warn', 4], quotes: ['error', 'single'], // 使用单引号 }, extends: [ 'plugin:vue/vue3-essential', 'eslint:recommended', '@vue/typescript/recommended', ], overrides: [ { files: [ '**/tests/*.{j,t}s?(x)', '**/tests/**/*.spec.{j,t}s?(x)', '**/tests/*.spec.{j,t}s?(x)', ], env: { mocha: true, }, }, ], };
vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') .BundleAnalyzerPlugin const IS_DEV = process.env.NODE_ENV !== 'production' /** * @todo 开发环境配置 * 某些实用工具,plugins 和 loaders 都只能在构建生产环境时才有用 * 在开发时使用 UglifyJsPlugin 来压缩和修改代码是没有意义的,不压缩 */ const DEVELOPMENT = webpackCOnfig=> { /** * @todo 启用 eval-source-map 更好的测试 * 每个模块使用 eval() 执行,并且 source map 转换为 DataUrl 后添加到 eval() 中。 * 初始化 source map 时比较慢,但是会在重新构建时提供比较快的速度,并且生成实际的文件。 * 行数能够正确映射,因为会映射到原始代码中。它会生成用于开发环境的最佳品质的 source map 。 */ webpackConfig.store.set('devtool', 'eval-source-map') webpackConfig.plugin('html').tap(([options]) => [ Object.assign(options, { minify: false, chunksSortMode: 'none' }) ]) // webpackConfig.plugin('BundleAnalyzerPlugin').use(BundleAnalyzerPlugin) return webpackConfig } /** * @todo 生产环境配置 * 每个额外的 loader/plugin 都有启动时间。尽量少使用不同的工具 */ const PRODUCTION = webpackCOnfig=> { /** * @todo 不需要启用 source-map,去除 console 的情况下 source-map 根本没用,还浪费大量时间和空间 * 详情见: https://webpack.js.org/configuration/devtool/#devtool */ webpackConfig.store.set('devtool', '') webpackConfig.plugin('html').tap(([options]) => [ Object.assign(options, { minify: { removeComments: true, removeCommentsFromCDATA: true, collapseWhitespace: true, conservativeCollapse: false, collapseInlineTagWhitespace: true, collapseBooleanAttributes: true, removeRedundantAttributes: true, removeAttributeQuotes: false, removeEmptyAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, minifyJS: true, minifyCSS: true }, cache: true, // 仅在文件被更改时发出文件 hash: true, // true 则将唯一的 webpack 编译哈希值附加到所有包含的脚本和 CSS 文件中,这对于清除缓存很有用 scriptLoading: 'defer', // 现代浏览器支持非阻塞 Javascript 加载('defer'),以提高页面启动性能。 inject: true, // true 所有 Javascript 资源都将放置在 body 元素的底部 chunksSortMode: 'none' }) ]) return webpackConfig } module.exports = { publicPath: '/', css: { loaderOptions: { less: { sourceMap: IS_DEV, lessOptions: { JavascriptEnabled: true } } } }, devServer: { proxy: 'http://10.10.10.115:8002' }, pluginOptions: { /** 全局加载 lss 的 webpack 插件 */ 'style-resources-loader': { preProcessor: 'less', patterns: ['./src/styles/index.less'] } }, /** * @description 去掉 console 信息 * config.optimization.minimizer[0].options.terserOptions.compress.drop_cOnsole= true; * html-webpack-plugin 插件配置详情见 https://github.com/jantimon/html-webpack-plugin#options */ configureWebpack: cOnfig=> { config.optimization = { splitChunks: { chunks: 'all', minSize: 3000, // (默认值:30000 )块的最小大小。 minChunks: 1, //(默认值:1 )在拆分之前共享模块的最小块数 maxAsyncRequests: 5, //(默认值为 5 )按需加载时并行请求的最大数量 maxInitialRequests: 6, // (默认值为 3 )入口点的最大并行请求数 automaticNameDelimiter: '-', name: true, cacheGroups: { lodash: { name: 'lodash', test: /[\\/]node_modules[\\/]lodash[\\/]/, priority: 20 }, vue: { name: 'vue', test: /[\\/]node_modules[\\/]vue[\\/]/ }, vuex: { name: 'vuex', test: /[\\/]node_modules[\\/]vuex[\\/]/ }, 'vuex-presistedstate': { name: 'vuex-presistedstate', test: /[\\/]node_modules[\\/]vuex-presistedstate[\\/]/ }, 'vue-router': { name: 'vue-router', test: /[\\/]node_modules[\\/]vue-router[\\/]/ }, 'ant-design-vue': { name: 'ant-design-vue', test: /[\\/]node_modules[\\/]ant-design-vue[\\/]/ }, moment: { name: 'moment', test: /[\\/]node_modules[\\/]moment[\\/]/, priority: 40 } } } } }, chainWebpack: cOnfig=> { config.resolve.symlinks(true) if (process.env.use_analyzer) { config.plugin('webpack-bundle-analyzer').use(BundleAnalyzerPlugin) } IS_DEV ? DEVELOPMENT(config) : PRODUCTION(config) }, productionSourceMap: false, lintOnSave: true }
![]() | 1 iold 2021-03-27 21:52:12 +08:00 你应该需要告诉 ts, *.vue 也是 ts 文件, ts 配置里 include 一下 ts 存在哪些文件后缀文件里. 例如 "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] |
![]() | 2 skypyb OP @iold 刚按照你说的试了下, 仍然不行。 其实是可以在 vue 里用 ts,也配置过了 shims-vue.d.ts ,只是有不少莫名其妙的问题 (比如我上边说的)。 |
3 cereschen 2021-03-27 22:45:45 +08:00 你这个报错是哪个服务报错的 发完整一点 |
![]() | 4 shakukansp 2021-03-28 00:31:37 +08:00 lang="ts" |
![]() | 5 EPr2hh6LADQWqRVH 2021-03-28 00:36:43 +08:00 Vue 和 TypeScript 不兼容的, 只能是主要逻辑单独写在外面的 ts 文件里,vue 只做引用调用。 想要 vue 里面使用 ts, 太难受了,yyx 不支持。 |
![]() | 8 ruoxie 2021-03-28 02:01:06 +08:00 直接 tsx 不香吗?写 template 没提示,还不如不用 TS https://github.com/lowcoding/lowcode-vscode/blob/vite2/webview-vue-webpack/src/views/snippet/Detail/index.tsx 写一个 vscode 插件 webview 部分的时候分别用 react 跟 vue3 撸了一次,简直不要太像 |
![]() | 9 Rocketer 2021-03-28 04:50:52 +08:00 via iPhone ![]() 个人感觉因为 Vue 定位于简单,所以就用最简单的 JS,这是匹配的。 想用 TS,就最好整体升级,用 React 或者 Angular 。非得用 TS 写 Vue,有种用专业咖啡机做速溶咖啡的感觉,没必要,也没什么好的效果。 |
![]() | 10 ericls 2021-03-28 04:52:53 +08:00 via iPhone ![]() 这就是我所说的 用做框架的思想做语言 肯定会出问题 |
![]() | 11 Zzzz77 2021-03-28 07:14:40 +08:00 via Android ![]() 首先 vue3 绝对绝对绝对是支持 ts 的,上面说不兼容的几位朋友应该是对 vue 并不太了解。 回到楼主的问题,第一点,script 标签应该是<script lang="ts">,而不是 type="ts",我不确定是不是你的笔误。 如果排除这一点,其实以上信息很难看出问题出在哪,我只能给几个建议: 一,如果方便的话,可以贴出仓库地址,大家可以帮你检查问题出在哪 二,去看看一些 vue3 + ts 的案例,看看区别在哪里,这种案例 github 一搜一堆,我前段时间也在 v 站上发过一个 vue3 + ts 的项目,你也可以翻我的主题看看 三,最简单有效的办法,直接用 cli 生成一个 vue3 + ts 的项目模板,对比检查问题出在什么地方 顺带一提,上面有朋友认为写 template 没提示,还不如不用 TS,个人不太认同,template 是可以通过 ide 插件(如 vscode )支持 ts 提示的,至于 template 和 tsx 哪个好,就见仁见智了~ |
![]() | 13 dumbass 2021-03-28 10:09:11 +08:00 via iPhone vue2 + composition-api + ts 写起来也蛮香的 |
![]() | 14 solos 2021-03-28 10:56:15 +08:00 建议换 angular |
![]() | 15 tolking 2021-03-28 11:55:18 +08:00 vscode + vetur 没有遇到这些问题,模版的提示据说要等到 setup 稳定后增加。毕竟不是标准的 ts,需要通过 ide 插件辅助支持。 |
16 Cbdy 2021-03-28 12:07:39 +08:00 via Android 应该不行 |
![]() | 17 beginor 2021-03-28 12:40:20 +08:00 via Android 要体验完整的 ts 支持, 建议试试 angular,ng 11 默认开启严格模式, 真是强迫症的福音! 另外 react 也不错, tsx 有特供的 ts 支持! 为啥非得在 vue 上吊死? |
18 suzic 2021-03-28 12:50:38 +08:00 via Android 我们就是那样用的,没碰到楼主说的问题。建议楼主检查下是不是 type='ts'的原因,正确的写法是"lang=ts" |
![]() | 19 emilll 2021-03-28 18:56:23 +08:00 楼主写法没错的 <script lang="ts"gt;</script> 另外 vue3 推荐使用 volar 插件 |
![]() | 20 hotsymbol 2021-03-28 22:11:01 +08:00 用 Typescript 写 Vue ?是脑子不好使吗?用 React 和 Angular 不能写 Typescript 吗?还是不思进取吗? |
![]() | 21 Jaosn 2021-03-29 00:07:22 +08:00 ![]() 这个帖子给我看乐了,几个回复也十分有趣,比如我楼上这位 |
![]() | 22 Sparetire 2021-03-29 02:54:13 +08:00 via Android 建议 Vue3 用 volar, Vue2 用 vetur |
![]() | 23 rodrick 2021-03-29 11:43:03 +08:00 不明白 vue 写 ts 怎么就有人觉得能上升到脑子不好了 |
24 xiaoliaoliao 2021-03-29 16:26:32 +08:00 推荐 volar 但是这插件也不是很成熟 eslint 没法用,如果需要未使用变量报错可以在 tsconfig 的 compilerOptions 中增加字段"noUnusedLocals": true |