TS入门001安装与调试

TypeScript

前置知识

  • 命令行知识(熟悉)

每门语言都有一些错误,而 TS 就是为了解决 JS 的错误

  • 安装,请保证版本一致(出了问题自己解决)

1
2
# 安装 typescript 命令行环境
npm install typescript@2.9.2 -g

安装成功后 会得到两个命令

  • tsc
  • tsserver
1
2
3
4
/usr/local/bin/tsc -> /usr/local/lib/node_modules/typescript/bin/tsc
/usr/local/bin/tsserver -> /usr/local/lib/node_modules/typescript/bin/tsserver
+ typescript@2.9.2
added 1 package from 1 contributor in 7.583s

安装 ts-node 让 node 支持 ts

1
2
3
4
5
6
npm install ts-node@7.0.0 -g

# 安装成功后 提示如下
/usr/local/bin/ts-node -> /usr/local/lib/node_modules/ts-node/dist/bin.js
+ ts-node@7.0.0
added 11 packages from 42 contributors in 1.49s

注意!请记住上述命令的路径,后面要用到

注意!请记住上述命令的路径,后面要用到

注意!请记住上述命令的路径,后面要用到

1
2
3
4
5
/usr/local/bin/tsc

/usr/local/bin/tsserver

/usr/local/bin/ts-node

调试

  1. 下载 vscode
    1. mac 按 command + K 之后在按 command + S
    2. 将格式化文件的快捷键绑定到自己喜欢的按键(我用的是 ctrl + L)
  2. 创建文件夹 tsdemo
  3. 用 vscode 打开 tsdemo 目录
  4. 创建 tsdemo/1.ts 作为我们的第一个 TS 文件
  5. 在文件里写一句 console.log(1) 保存
  6. Windows 用户注意了,这里需要单独运行一些命令(Linux 用户和 macOS 用户不用执行)
    • npm init -y
      • npm i -D ts-node typescript
  7. 创建 tsdemo/.vscode/launch.json 文件,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    {
    "configurations": [
    {
    "name": "ts-node",
    "type": "node",
    "request": "launch",
    "program": "注意看这里,要写成ts-node对应的可执行文件,Windows 用户注意了,你应该写成 ${workspaceRoot}/node_modules/ts-node/dist/bin.js",
    "args": ["${relativeFile}"],
    "cwd": "${workspaceRoot}",
    "protocol": "inspector"
    }
    ]
    }

    复制刚才的 ts-node 路径 /usr/local/bin/ts-node
    {
    "configurations": [
    {
    "name": "ts-node",
    "type": "node",
    "request": "launch",
    "program": "/usr/local/bin/ts-node",
    "args": ["${relativeFile}"],
    "cwd": "${workspaceRoot}",
    "protocol": "inspector"
    }
    ]
    }
  8. 打开 tsdemo/1.js,找到调试选项(小虫子图标),选择 ts-node,然后点击调试 在点击那个绿色箭头

    1
    2
    但是此时报错了,因为你没选中那个1.ts文件
    此时切换到 1.ts的文件 再次点击调试

参考文章: https://segmentfault.com/a/1190000011935122

至此我们运行了第一个 ts程序

tsc的使用

greeter.ts

1
2
3
4
5
6
7
function greeter(person) {
return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

在命令行,注意当前 greeter.ts 所在路径

1
2
3
4
5
6
7
8
tsc greeter.ts

# 此时生成了 greeter.js
function greeter(person) {
return "Hello, " + person;
}
var user = "Jane User";
document.body.innerHTML = greeter(user);

你会说跟原来没啥区别啊

  • 只不过去除了空行吗?
  • 如果你写的仅仅是 JS 那编译后就是 JS

为什么 要tsc 编译一下呢?

1
2
3
4
5
6
7
8
1. 浏览器可以直接运行 JS
2. 浏览器不可以直接运行 TS
⬇️
⬇️
3. 要把 TS 变成 JS ,才能运行

==> tsc
==> type script compiler typescript编译器

再看文档示例

  • 他想规定 greeter函数接受的参数是一个字符串
1
2
3
4
5
6
7
function greeter(person: string) {
return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

编译后竟然还跟之前的内容一样

解析 function greeter(person: string)

修改 greeter.ts

1
2
3
4
5
6
7
function greeter(person: string) {
return "Hello, " + person;
}

let user = [1,2,3];

document.body.innerHTML = greeter(user);
  • 再次运行 tsc greeter.ts,此时报错了
1
2
3
4
5
6
7
 Argument of type 'number[]' is not assignable to parameterof type 'string'.

7 document.body.innerHTML = greeter(user);

/*
意思 你的 user 是一个数组,但是函数里说要一个字符串,所以无法变成js
*/

中间发生了什么

1
2
3
4
5
         通过 tsc
TS -------------------> JS
1.类型检查

如果你 TS 中期待的类型传入不会 就无法编译为 JS

为什么做类型检查?

如果不用 ts 你就要这样写

1
2
3
4
5
6
7
8
function greeter(person) {
if(typeof person !== 'string'){
throw new Error('person 必须是一个字符串')
}
return "Hello, " + person;
}
var user = [1, 2, 3];
document.body.innerHTML = greeter(user);

此时有什么问题吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
程序必须运行到
if(typeof person !== 'string'){...}
才能提示用户


而 TS 不一样,它是在你编译的时候就告诉你 写错了

----------------------------------------
通过 tsc
TS -------------------> JS
1.类型检查
用 JS 检查:执行到 greeter(user) 报错 运行时报错
用 TS 检查:编译时报错

有区别吗?

执行的 greeter 时候 代码已经到服务器了,用户感知不到的,程序执行到哪里报错了,你难道让用户改吗?

所以如果我们在 上传代码之前就知道这个错是不是可以 及时改过来

接口 interface

1
2
3
4
5
6
7
8
9
10
11
12
interface Person{
姓:string,
名:string
}

function greeter(person: Person) {
return "Hello, " + person.姓 +person.名;
}

let user = {姓:'漩涡',名:'鸣人'};

console.log( greeter(user) );

只有姓 没有名 行不行?

1
2
3
4
5
6
7
8
9
10
11
12
13
let user = {姓:'漩涡'};

报错
error TS2345: Argument of type '{ 姓: string; }' is not assignable to parameter of type 'Person'.
Property '名' is missing in type '{ 姓: string; }'.
--------------------------------
如果你用传统 js
function greeter(person) {
return "Hello, " + person.姓 +person.名;
}

如果 person没有 姓/名
就会返回 Hello undefined undefined

类 class

继续抄文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student {
全名: string;
constructor(public 姓, public 名) {
this.全名 = 姓 + 名;
}
}

interface Person {
姓: string;
名: string;
}

function greeter(person : Person) {
return "Hello, " + person.姓 + " " + person.名;
}

let user = new Student("漩涡", "鸣人");

console.log(greeter(user));

public 的含义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student {
全名: string;
constructor(public 姓, public 名) {
this.全名 = 姓 + 名;
}
}

相当于
class Student {
全名: string;
姓:string;
名:string;
constructor(姓, 名) {
this.姓 = 姓;
this.名 = 名;
this.全名 = 姓 + 名;
}
}

此时我能在 greeter 里获取 全名 吗?

1
2
3
4
5
6
7
8
9
10
11
12
function greeter(person : Person) {
return "Hello, " + person.全名;
}

报错
Property '全名' does not exist on type 'Person'.


如果你想要全名唯一的办法就是改参数类型
function greeter(person : Student) {
return "Hello, " + person.全名;
}

如何学TS

  • CRM
  • 单纯 既然学TS 就不要去搞 webpack / vue

    1
    2
    什么时候去整 webpack / vue
    你已经入门了 知道大概的错如何解决。再去结合其他东西
  • 不要看书(它不够新)——看文档和博客

打开 ts 文档

https://www.tslang.cn/docs/home.html

挨个看,哪里没见过就重点看

函数部分

要求输入两个参数,类型都为 number,返回值为 number

1
2
3
function add(a:number,b:number):number{
return a+b;
}
  • 如何实现重载
1
2
3
4
5
6
7
function add(a:number,b:number):number;
function add(a:string,b:string):string;
// 最后一种一定要兼容上面几种
// any 就是任何类型
function add(a:any,b:any):any{
return a+b;
}
  • 返回数组类型
1
2
3
4
function getArr(arr:number[]) : number[]{
...
return [1,2,3,4,5];
}

tuple 元组

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

1
2
3
4
5
6
// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Person{
gender:string
}

function merry(a:Person,b:Person):[Person,Person]{
if(a.gender !== b.gender){
return [a,b];
}else{
throw new Error('同性不能结婚')
}
}

let a = {gender:'男'};
let b = {gender:'女'};

console.log(merry( a , b ));

代码此时有个问题就是 如果它写 let b = {gender:’狗’} 也成功了

枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
enum Gender{
Male,
Female
}
interface Person{
gender:Gender
}

function merry(a:Person,b:Person):[Person,Person]{
if(a.gender !== b.gender){
return [a,b];
}else{
throw new Error('同性不能结婚')
}
}

let a = {gender:Gender.Male};
let b = {gender:Gender.Female};

console.log(merry( a , b ));