- Published on
TypeScript 从入门到放弃之快速入门
前言
尝试了一下 TypeScript 之后,是“真香”啊,静态类型检验确实能避免很多编译时的问题。学有余力之际,所以打算先过一遍官方文档。本系列是以官方文档为主,结合自身相关经验整理而成的入门学习笔记。
TypeScript 速览
安装 TypeScript
$ npm install -g typescript
编译
// greeter.ts
function greeter(person) {
return 'Hello, ' + person
}
let user = 'Jane User'
document.body.innerHTML = greeter(user)
$ tsc greeter.ts
编译后会得到同名的 js 文件。
类型注解(Type annotations)
function greeter(person: string) {
return 'Hello, ' + person
}
let user = 'Jane User'
document.body.innerHTML = greeter(user)
加上注解(其实,不加类型注解,变量类型应该是 any )后,编译会经过类型检查,不正确会报错,但是仍然会生成相应的 js 文件。
接口(Interfaces)
描述对象字段类型。只要对象包含接口中的必须字段即可,多余字段不做检查。
类(Classes)
可包含公有变量和构造器。值得注意的是,构造函数的参数上使用 public 等同于创建了同名的成员变量。
class Student {
fullName: string
constructor(
public firstName: string,
public middleInitial: string,
public lastName: string,
) {
this.fullName = firstName + ' ' + middleInitial + ' ' + lastName
}
}
interface Person {
firstName: string
lastName: string
}
function greeter(person: Person) {
return 'Hello, ' + person.firstName + ' ' + person.lastName
}
let user = new Student('Jane', 'M.', 'User')
document.body.innerHTML = greeter(user)
例如本例中,编译后得到的结果如下:
var Student = /** @class */ (function () {
function Student(firstName, middleInitial, lastName) {
this.firstName = firstName
this.middleInitial = middleInitial
this.lastName = lastName
this.fullName = firstName + ' ' + middleInitial + ' ' + lastName
}
return Student
})()
function greeter(person) {
return 'Hello, ' + person.firstName + ' ' + person.lastName
}
var user = new Student('Jane', 'M.', 'User')
document.body.innerHTML = greeter(user)
如果去掉 middleInitial
的 public
修饰,则 this.middleInitial = middleInitial;
会被移除。
运行 TypeScript Web 应用
新建如下 greeter.html
<!DOCTYPE html>
<html>
<head>
<title>TypeScript Greeter</title>
</head>
<body>
<script src="greeter.js"></script>
</body>
</html>
使用浏览器打开,可得输出
Hello, Jane User
快速入门
官方提供了基于多种框架的入门教程,这里列一下我知名知意的教程
因为我是从 React 入手 TypeScript 的,故仅作基于 React 入门笔记。
TypeScript React 入门
安装 create-react-app
$ npm install -g create-react-app
创建新项目
$ create-react-app my-app --scripts-version=react-scripts-ts
react-scripts-ts is a set of adjustments to take the standard create-react-app project pipeline and bring TypeScript into the mix.
我的理解是 react-scripts-ts 是一个给标准的 create-react-app 项目混合 TypeScript 支持的管道。
关于目录结构的说明,详见官方文档
代码管理
$ git init
$ git add .
$ git commit -m "Initial commit."
重写默认 TSLint 配置( tslint.json / tslint.yaml )
由于 react-scripts-ts 预设的配置有些过于热心(a bit overzealous,还真不知道怎么翻译好),所以修改如下。
{
- "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
+ "extends": [],
+ "defaultSeverity": "warning",
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts"
]
}
}
关于配置 TSLint,这个作为补充,为了定制化配置,需要研究下。
启动
$ npm run start
测试
$ npm run test
所有以 .test.ts
和 spec.ts
的文件,都会被 Jest 运行。特别的, Jest 也会像 npm run start
一样自动运行。
编译
$ npm run build
创建一个组件
通过类创建的组件可以使用状态和生命周期函数,由于 React 16.8 之后提供的 hooks ,我们已经可以在函数式组件中使用一些特殊功能,包括状态管理。
偶然看到一个讨论 React 16.7 - React.SFC is now deprecated ,进而找到 Rename React's SFC to 'FunctionalComponent',官方已经修改了 SFC 定义 _(:3J∠)_
类型断言(Type assertions)
类似这样 document.getElementById('root') as HTMLElement
的 as
语法,被称为类型断言,或者类型转换。这是一个非常重要的方式去告诉类型检查器( type checker )我们使用的对象究竟是什么类型。
举个例子,定义一个 CommentType
的类型,当我们从后台请求了响应的评论列表 comments
时,就可以使用如下的方式告诉类型检查器我们得到的是一个 CommentType
数组。
declare type CommentType = {}
// ...
comments as CommentType[]
这里 getElementById
的返回类型是 HTMLElement | null
,所以我们使用 as
语法让 TypeScript 确信为 HTMLElement
类型。
状态组件
为状态组件添加类型校验的使用方式如下:
interface HelloProps {
name: string
}
interface HelloState {
current: string
}
class Hello extends React.Component<HelloProps, HelloState> {
// ...
}
备注:
- Typescript: Interfaces vs Types - 最大的区别就是 interface 可以声明合并( Declaration Merging )
添加样式
和通常的方式一致。
使用 Jest 编写测试
首先,需要安装 EnzyMe 。默认情况下,应用包含了一个叫 jsdom 的库,用于模拟 DOM 树并测试其运行时行为。 EnzyMe 是基于 jsdom 的让用户更为简单的访问组件的行为。
$ npm install -D enzyme @types/enzyme enzyme-adapter-react-16 @types/enzyme-adapter-react-16 react-test-renderer
关于配置和入门使用,参阅本节官方文档。
添加状态管理器
介绍了 Redux 和 MobX,并基于 Redux 做了较为详细的讲解。如果都在看 TS 的文档了,状态管理应该已经很熟悉了吧,这里著作赘述了。
弹出配置
如果想自定义 create-react-app 的配置,需要用到弹出配置的功能。
$ npm run eject
在学习 ant-design 的时候,接触到了 react-app-rewired ,可以在不弹出配置的情况下重写相关配置,个人觉得通常情况下这个应该是个不错的选择。
下一步
多学习 React 官方文档,还有很多其他的技术需要学习,诸如状态管理,项目配置,页面路由等等...