interface Pointlike {
x: number;
y: number;
}
interface Named {
name: string;
}
function logPoint(point: Pointlike) {
console.log("x = " + point.x + ", y = " + point.y);
}
function logName(x: Named) {
console.log("Hello, " + x.name);
}
const obj = {
x: 0,
y: 0,
name: "Origin",
};
logPoint(obj);
logName(obj);
可以把obj
作为Pointlike
的一个实例,因为obj
有Pointlike
的两个成员
一个对象内部具体包含什么成员决定了
他是什么类型,而不是他被声明为什么,他就是什么类型的实例
面向对象的基本原则:派生类必须包含基类的所有属性,ts
也遵循了这个规则,只不过隐式的帮我们创建了一个派生类和基类之间的关系
A subclass cannot remove a property of its base class, because doing so would destroy the natural subtype relationship between the derived class and its base. Structural type systems simply identify this relationship implicitly by describing subtypes in terms of having properties of compatible types.
同理,这样也是被允许的
class Car {
drive() {
// hit the gas
}
}
class Golfer {
drive() {
// hit the ball far
}
}
// No error?
let w: Car = new Golfer();
因为
ts
的类型系统是完全擦除的
npm i -g typescript
# 添加 tsc 编译器
yarn add -D typescript
# 添加 ts 基础配置文件
yarn add -D @tsconfig/node12
{
"compilerOptions": {
// 与 Vue 的浏览器支持保持一致
"target": "es5",
// 这可以对 `this` 上的数据 property 进行更严格的推断
"strict": true,
// 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake:
"module": "es2015",
"moduleResolution": "node"
},
"extends": "@tsconfig/node12/tsconfig.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
# 在工程根目录 启动 tsc
# -watch 使其自动编译发生变化的 ts 文件
# -proect . 指定编译整个工程 要求当前目录下有一个 tsconfig.json 的文件
tsc -project . -watch
# 同时启动项目
yarn serve
vue-cli 是一个全局的脚手架
vue-cli-service serve
命令会启动一个开发服务器 (基于 webpack-dev-server) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。所以我们只需要在 vue cli 配置 webpack 的 loaders 就能让整个工程自动编译
typescript
了
# webpack 使用 ts-loader 来加载 .ts 文件
# typescript 用于编译 ts
yarn add -D ts-loader@8 typescript
在vue.config.js
中配置webpack
新增一个针对.ts
.tsx
文件的loader
在
webpack
中配置自动添加对ts
tsx
文件的扩展名⚠️ 在
vue.config.js
中配置的configureWebpack
相关的会被合并到最终的webpack
的配置文件中到此,文件扩展名为
.ts
.tsx
的typescript
代码已经能被ts-loader
正常加载和tsc
编译但是
.vue
组件中也含有typescript
代码,所以需要额外声明tsloader
的appendTsSuffixTo
属性
module.exports = {
/***
* https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
* */
configureWebpack: {
resolve: {
extensions: ['.js', '.ts', '.tsx'],
},
},
chainWebpack: (config) => {
config.module
.rule('ts')
.test(/\.tsx?$/)
/* .use('cache-loader')
.loader('cache-loader')
.options({
cacheDirectory: resolve('node_modules/.cache/ts-loader')
})
.end()*/
.use('babel-loader')
.loader('babel-loader')
.end()
.use('ts-loader')
.loader('ts-loader')
.options({
transpileOnly: false, // 如果为 true 则 关闭类型检查,即只进行转译(类型检查交给webpack插件(fork-ts-checker-webpack-plugin)在另一个进程中进行,这就是所谓的多进程方案,如果设置transpileOnly为false, 则编译和类型检查全部由ts-loader来做, 这就是单进程方案.显然多进程方案速度更快)
// https://github.com/TypeStrong/ts-loader
appendTsSuffixTo: ['\\.vue$'],
happyPackMode: false
})
.end()
}
}
配置完成typescript
之后,查看对typescript
的配置详情
# 命令行执行
vue inspect --rule ts
/* config.module.rule('ts') */
{
test: /\.tsx?$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
transpileOnly: false,
appendTsSuffixTo: [
'\\.vue$'
],
happyPackMode: false
}
}
]
}
# 查看所有的 vue-cli 配置
vue inspect
resolve: {
alias: {
# 导入组件时的 @ 前缀别名就是在这里进行配置的
'@': '/Users/luojun/webstorm_project/Saber/src',
vue$: 'vue/dist/vue.runtime.esm.js'
},
extensions: [
'.mjs',
'.js',
'.jsx',
'.vue',
'.json',
'.wasm',
'.js',
'.ts',
'.tsx'
],
}
⚠️ 要让 TypeScript 正确推断 Vue 组件选项中的类型,您需要使用
Vue.component
或Vue.extend
定义组件
<template>
<div>
<div v-text="msg"></div>
<el-button @click="changeMsg">点我</el-button>
</div>
</template>
<script lang="ts">
// 需要指定语言类型为 typescript
// 因为 vue.config.js 中 configureWebpack 配置了不需要指定 ts 的扩展名,所以这里不需要添加 .ts 后缀
import {add} from "./demo";
import vue from "vue";
// 必须使用 vue.extend() 或者 vue.component 来定义一个组件
export default vue.extend({
name: "hello",
data() {
return {
msgTemplate:"你好" ,
msg: '',
count: 0,
}
},
methods: {
addOne(a: number): number {
// add(a, "")
return add(a, 1)
},
changeMsg():void {
this.count = this.addOne(this.count)
this.msg = this.msgTemplate + " " as string+ this.count
}
}
})
</script>
<style scoped>
</style>
demo.ts
文件
export function add(a: number, b: number): number {
console.log("监控中",a,b)
return a + b
}
yarn serve
yarn run v1.22.19
$ vue-cli-service serve
INFO Starting development server...
98% after emitting CopyPlugin
ERROR Failed to compile with 1 error 11:09:35 AM
error in ./src/main.js
Syntax Error: TypeError: loaderContext.getOptions is not a function
@ multi (webpack)-dev-server/client?http://192.168.1.140:1888/sockjs-node (webpack)/hot/dev-server.js ./src/main.js
降低
ts-loader
的版本或者升级webpack@5
# 二选一 yarn add -D ts-loader@8 yarn add webpack@5.75.0
error in /Users/luojun/webstorm_project/Saber/src/views/usermenu/hello.vue.ts
[tsl] ERROR in /Users/luojun/webstorm_project/Saber/src/views/usermenu/hello.vue.ts(2,19)
TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
解决:通过前面的在
vue.config.js
中的configureWebpack
添加对.ts
.tsx
的支持
in /Users/luojun/project/java_script/type_script/old_vue2/src/components/demo.ts
[tsl] ERROR in /Users/luojun/project/java_script/type_script/old_vue2/src/components/demo.ts(6,24)
TS2307: Cannot find module '!../../node_modules/@vue/vue-loader-v15/lib/runtime/componentNormalizer.js' or its corresponding type declarations.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。