TypeScript 编译器能直接理解什么,与框架自己定义的文件格式之间存在边界。
Vue 单文件组件的语言边界
Vue 的单文件组件(SFC)不是标准 TypeScript:
<template>
<div>{{ count }}</div>
</template>
<script setup lang="ts">
const count = ref(0)
</script>
一个 .vue 文件包含多个语言区域:
<template>:模板语法,不是 JavaScript<script>:TypeScript / JavaScript<style>:CSS / SCSS / Less
TypeScript 编译器只理解 <script> 部分。<template> 里的 {{ count }}、v-if、v-for 不是标准 JavaScript,TypeScript 无法直接解析。
vue-tsc / Volar 的作用
Vue 生态需要 vue-tsc / Volar 来桥接这个边界:
.vue 文件
↓
vue-tsc / Volar 解析
↓
提取 <script> → 交给 TypeScript
提取 <template> → 转换成 TypeScript 能理解的形式
↓
类型检查
↓
映射回模板
vue-tsc 是 Vue 的 TypeScript 编译器,它理解 .vue 文件格式,内部调用 TypeScript 来做类型检查。
Volar 是 VS Code 的 Vue 语言插件,它实现了 Vue 的语言服务,内部也使用 TypeScript。
Angular 的情况
Angular 有自己的模板语法和编译器:
@Component({
template: `
<div *ngIf="show">{{ message }}</div>
<button (click)="handleClick()">Click</button>
`
})
export class AppComponent {
show = true
message = 'Hello'
handleClick() { ... }
}
Angular 的 @angular/compiler-cli 需要:
- 解析 Angular 模板语法
- 类型检查模板中的表达式
- 生成类型安全的代码
这需要额外的工具链来适配 TypeScript。
设计选择,不是优劣问题
React 选择让 JSX 成为 TypeScript 的原生语法扩展,获得了开箱即用的 TypeScript 体验。
Vue 选择让 SFC 包含模板、脚本、样式三个区域,获得了更好的关注点分离,但需要额外的工具链来处理类型检查。
Angular 选择让模板有自己的一套语法,获得了更强的模板能力,但同样需要额外的工具链。
这不是"谁更好谁更差",而是不同的设计选择:
- React:模板就是 JavaScript 表达式,TypeScript 直接理解
- Vue:模板是独立的语言,需要工具桥接到 TypeScript
- Angular:模板有自己的语法,需要编译器处理类型
TypeScript 编译器能理解什么,取决于框架选择让模板和 JavaScript 的关系有多近。