1.TypeScript安装和基础
目录
安装TypeScript
# 全局安装
npm install -g typescript
# 更新
npm update typescript -g
# 查看TypeScript版本
tsc -v
TS编译成JS
hello.ts
console.log('hello typescript')
tsc hello.ts
hello.js
console.log('hello typescript');
优化编译
解决TS和JS冲突问题
# 生成配置文件,tsconfig.json
tsc --init
# 自动编译
tsc --watch
# 当ts有错误的时候不允许编译成js
tsc --noEmitOnError --watch
显示类型
变量名:类型
function print(name: string, date: Date){
console.log(`hello ${name}, 现在是:${date}`)
}
print('小明', new Date())
降级编译
在tsconfig.json配置文件中配置,找到 Language and Environment 这个位置
将target的值修改为:es5/es3
{
// "target": "es2016",
"target": "es5",
}
hello.ts 文件
// console.log('hello typescript')
function print(name: string, date: Date){
console.log(`hello ${name}, todat is ${date}`)
}
print('小明', new Date())
编译es5语法hello.ts文件
// console.log('hello typescript')
function print(name, date) {
console.log("hello ".concat(name, ", todat is ").concat(date));
}
print('小明', new Date());
严格模式
一般默认情况下开启严格模式
{
"strice": true,
"noImplicitAny": true,
"strictNullChecks": true,
}
基础类型
类型 | ||
---|---|---|
string | ||
number | ||
boolean |
base-type.ts
let str : string = 'hello string'
let num : number = 10
let flag : boolean = true
数组
定义
let strList: string[] = ['a', 'b', 'c']
let numList: Array<number> = [1, 2, 3]
any
let obj: any = {
x: 0
}
obj.test()
obj.name = 'any name'
const loginFlag: boolean = obj.isSucces
编译后
let obj = {
x: 0
};
obj.test();
obj.name = 'any name';
const loginFlag = obj.isSuccess;
运行报错:
/Users/wuhuaming/WebstormProjects/TypeScript/base02/dist/base-type.js:10
obj.test();
^
TypeError: obj.test is not a function
at Object.<anonymous> (/Users/wuhuaming/WebstormProjects/TypeScript/base02/dist/base-type.js:10:5)
at Module._compile (node:internal/modules/cjs/loader:1241:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
at node:internal/main/run_main_module:23:47
对象类型&函数
function printCoord(pt: {x: number, y: number}) {
console.log('x坐标:' + pt.x)
console.log('y坐标:' + pt.y)
}
printCoord({
x: 3,
y: 4
})
function printName(obj: {firstName: string, lastName?: string}){
console.log('firstName: ' + obj.firstName.toLocaleLowerCase)
console.log('lastName:' + obj.lastName?.toLocaleLowerCase)
}
printName({
firstName: 'wuji',
lastName: 'Zhang'
})
- 如果参数是可选的,参数后面添加**?**
- 在不确定字段是否是undefined的时候也可以使用**?**来安全的调用其方法
联合类型
两个或多个其他类型组成的类型
let id: number | string
表示id既可以是数值型也可以是字符串类型
function printId(id: number | string) {
console.log(id)
}
printId(100)
printId('1024')
typeof运用
const log = console.log
function printString(s: string[] | string | number){
if(Array.isArray(s)){
log(s.join(' , '))
}else if(typeof s === 'string'){
log(s.toUpperCase())
}else{
log(s)
}
}
printString(['a', 'b', 'c'])
printString('w')
printString(10)
function getFirstThree(x: number[] | string){
return x.slice(0, 3)
}
log(getFirstThree('abcdefg'))
log(getFirstThree([1,2]))
类型别名
//
type Point = {
x: number;
y: number;
}
//
type Point = {x: number, y: number}
//
type MyId = number | string
- 类型名称一般以大写字母开头
接口
interface MyPoint {
x: number
y: number
}
接口之间继承
interface Animal{
name: string
}
interface Bear extends Animal {
honey: boolean
}
const bear: Bear = {
honey: true,
name: "winie"
}
console.log(bear.name)
console.log(bear.honey)
接口和类型别名的区别
- 类型别名创建以后,不能在扩展字段,接口可以扩展字段
类型断言 as
const myApp = document.getElementById('myApp') as HTMLCanvasElement
const myApp1 = <HTMLCanvasElement> document.getElementById('myApp')
const asObj = ('16' as unknown) as number
文字类型
const
-
const: 声明一个只读的变量,声明后,值就不能改变
-
const必须初始化
-
const并不是变量的值不能改动,而是变量指向的内存地址所保存的数据不得改动
const obj = { age: 17 } obj.age = 18; // ok obj = { age: 18 } // SyntaxError: Identifier 'obj' has already been declared
let
-
不存在变量提升,let声明变量前,该变量不能使用(暂时性死区)。
-
let命令所在的代码块内有效,在块级作用域内有效
{ let a = 10; } console.log(a); // ReferenceError: a is not defined
-
let不允许在相同作用域中重复声明,注意是相同作用域,不同作用域有重复声明不会报错
let a = 10; let a = 20; // Uncaught SyntaxError: Identifier 'a' has already been declared let a = 10; { let a = 20; } // ok
var
-
存在变量提升
console.log(a); // undefined var a = 10; // 编译过程 var a; console.log(a); // undefined a = 10;
-
一个变量可多次声明,后面的声明会覆盖前面的声明
var a = 10; var a = 20; console.log(a); // 20
-
在函数中使用var声明变量的时候,该变量是局部的
var a = 10; function change(){ var a = 20; } change(); console.log(a); // 10
文字类型
function printText(s: string, aligenment: 'left' | 'center' | 'right') {
// todo
}
printText('hello', "left")
function compare(a: number, b: number): -1 | 0 | 1 {
return a === b ? 0 : a > b ? 1 : -1
}
console.log(compare(2, 3))
console.log(compare(2, 2))
console.log(compare(2, 1))
interface Options {
width: number
}
function config(x: Options | 'auto') {
// todo
}
config({ width: 1080})
config('auto')
枚举
enum Direct {
Up = 1,
Down,
Left,
Right,
}
console.log(Direct.Up)
console.log(Direct.Right)
结果:
1
4
类型缩小
typeof 类型守卫
typeof str === "object" | "string" | "number" | "boolean" | "bigint" | "symbol" | "undefined" | "function"
function printAll(s: string | string[] | null){
if(s !== null && typeof s === 'object'){
for(const str of s){
console.log(str)
}
}else if (typeof s === 'string'){
console.log(s.toUpperCase())
}else{
console.log('s is null')
}
}
printAll(['a', 'b', 'cdfgj'])
printAll('a')
printAll(null)
真值缩小
console.log(Boolean('hello'))//true
console.log(!!'hello')//true
等值缩小
in 操作符缩小
type Fish = { swim: ()=> {}}
type Bard = { fly: () => void}
// type People = { swim?: ()=> void, fly?: () => void}
function move(animal: Fish | Bard) {
if('swim' in animal){
return animal.swim()
}
return animal.fly()
}
instanceof
function printDate(str: Date | string){
if(str instanceof Date){
console.log(str.getDate())
}else{
console.log(str.toUpperCase())
}
}
printDate(new Date())
printDate('hello word')
类型谓词
type Fish = {
name: string
swim: ()=> void
}
type Bard = {
name: string
fly: () => void
}
function isFish(animal: Fish | Bard): animal is Fish {
return (animal as Fish).swim !== undefined
}
function getAnimal(num: number): Fish | Bard {
let fish: Fish = {
name: "sharkey",
swim: function () {
console.log(this.name + 'swimming')
}
}
let bard: Bard = {
name: "sparrow",
fly: function (): void {
console.log(this.name + 'flying')
}
}
return num === 1 ? fish : bard
}
const zoo: (Fish | Bard)[] = [getAnimal(1), getAnimal(0), getAnimal(0), getAnimal(1)]
const fishList = zoo.filter(isFish)
const fishList1 = zoo.filter(isFish) as Fish[]
const fishList2 = zoo.filter((item): item is Fish => {
if(item.name === 'frog' || item.name === 'sparrow'){
return false
}
return isFish(item)
})
console.log(fishList)
console.log(fishList1)
console.log(fishList2)
结果:
[
{ name: 'sharkey', swim: [Function: swim] },
{ name: 'sharkey', swim: [Function: swim] }
]
[
{ name: 'sharkey', swim: [Function: swim] },
{ name: 'sharkey', swim: [Function: swim] }
]
[
{ name: 'sharkey', swim: [Function: swim] },
{ name: 'sharkey', swim: [Function: swim] }
]