文章目录
是啥?为什么用ts(优点)
- ts是js的超集, js能做的,ts也能, 但是还是转换成js执行 还可以用es新特性…(微软开源的)
- 方便维护
- 因为类型确定, 就有了代码提示, 所有变量、函数和类都可以快速溯源, 提升开发体验.
javascript 对比 java
javascript | java |
---|---|
动态弱类型: 变量可赋值其他类型 | 静态强类型 |
解释型/脚本语言(无编译环节) | 编译型(.java 编译(同时做类型检查)成 .class ) |
单双引号 一样 | 单引号是字符, 双引号 字符串 |
句末分号可有可无 | 必须有分号 |
方法的定义可以嵌套 | 不能 |
逻辑 && || 循环 分支 语法相同 | – |
class Person{
public a: string = 'a' // 实例属性
static id: string = 'a' // 静态属性, 实例属性不能访问, 要类访问
private name: string = 'zhangmingle' // 私有属性, 外部和继承都不能访问, 不写默认是public
protected age: string = '32' // 可在继承中类里访问,不能外部(public和private 的折中)
readonly b // 只读属性, 一般用不上.
get name() { // ts可以这样写
return this._name;
}
}
constructor(public name: string, public age: number) { // 就不用写this.name = name....
}
开发环境搭建
- 安装node.js
- 全局安装 typescript
- tsc a.ts
一些问题
- 用元祖, eslint一直报这个错!!!Cannot read property ‘map’ of undefined
- Promise ??
- 类型别名
基础类型
const a: string = 'boo' // 类型推论
const b: number = 123 // 可 NaN Infinity
const c: boolean = true // 可以为 null undefined 但是得取消严格模式
const e: null = null
const f: undefined = null
if(typeof s === 'string') { // typeof对unknown类型进行判断
}
参数默认值也可
function sum(x: number, y?: number, ...res: number[]): number {
return x + y;
}
// 函数表达式
let mySum: (x: number, y: number) => number = function () {}
1. 字面量 const a: male | female; let a: 10; 一般不用 联合类型( | )
一些修饰符: ? 可选 | 联合 & 同时满足, { name: age } & {}
基本类型 | 举例 | 描述 |
---|---|---|
number/string/boolean | ||
字面量 | 其本身 | 限制变量的值为该字面量 |
any | * | 关闭类型检测, 赋值给别人, 别人也会变any !!! |
unknow | 赋值给其他类型, 就会报错 | |
void | 通常用来设置函数返回值 | |
enum | enum { a, b } | 枚举 |
tuple | 固定长度的数组 | |
null/undefined | 是所有类型的子类型?? | |
object/array | ||
never | 永远不会返回结果, throw new Error(‘报错了’) 少 |
数组
const arr1: Array<number> = [1, 2, 3]; // 两种形式
const arr2: number[] = []; // 这种用得更多
[{}, {}]// 数组里面一堆对象,怎么限制这个数组???
let a: object[] // 这样再怎么限制对象的结构呢??
元祖
- 有什么用??? 固定长度的数组
// 只能写成数组的样式,不能像枚举那样, 可以搭配类型别名 type使用
const tuple: [number, string] = [12, 'sfda'] //
cosnt [age, name] = tuple; // 解构 useState返回元祖?
// 写了元祖的时候 eslint报错 Parsing error: Cannot read property 'map' of undefined
.eslintrc.js
parserOptions: {
parser: " @typescript-eslint/parser" // babel-eslint
}
Object.entries({ foo: 123, bar: 456}) ??元祖???
类型断言
变量 as 类型;
let <string> a;
-
用es6语法报错.(symbol promise) 配置 “lib”: [“es2015”, “DOM”] 标准库(内置对象所对应的声明)
标准库是内置对象对应的声明. (比如你用es6语法, 必须有es2015的声明) -
ts 报错重复定义, 作用域. 可以放立即执行函数里面或者 export {} (模块作用域?) 实际开发基本不用
-
类型断言有什么用? 两种写法?
就是我们确定它是某个类型, 但是编译器不知道, 我们手动判断一下 a as string 或者 a 建议统一用as
// jsx不能使用. 类型断言并不是类型转换.
枚举
1. 可以给数值取名字 // 不写的话默认从0开始累加. 使用的话 Post.a
enum Post {
a = 1, // 不赋值的话默认从0开始累加
b = 2 // 等于号, 逗号
}
常量枚举, 前面加 const (如果不需要通过值找到键, 则可以用这个)
接口
- a:object 指所有的非原始类型
const foo: object = function() {} // 不单指对象 [] {}; 所以基本不用
const obj: { name: string } = { name: 'zhangmingle' } // 用这种, 有了上面这种, 为什么还要用接口?????
// 接口用来约定对象的结构. 不逗
interface Person {
readonly id: number // 只读
age?: number; // 可选
[prop : string]: any; // 这样就能添加任意数量的其它属性了
run(): void;
}
interface a{
name: string
}
interface b{
age: 12
} // 这样写会合并, 不是覆盖!!!!!!!!!!!
接口和type类似, 不同的是, 接口还可以限制类.
implements 实现接口 (可以多个) class A implements B,c{}
装饰器
- Promise
- | & 一个或一个且
- 类型别名 type mytype = 1 | 2 | 3 | 4;
抽象类
抽象类只能继承了, 不能new 继承 实现 多态.(面向对象的三大特征: 封装 继承 多态)
abstract class Person {
name: string //
pravite age: number // 私有属性
constructor(name: string, age: number) {
this.name = name
this.age =age
}
eat(food: string): void{
console.log(food)
}
abstract eat(food: string):void // 抽象方法. 有抽象方法的类必须定义为抽象类,
}
和接口的区别是抽象类可以包含一些具体的实现
export {} 可以让该文件模块化, 就有了作用域, 不会变量冲突 写了es6模块化, 默认严格模式.
泛型
函数 接口 类 没有指定具体的类型, 主要是为了复用
Array<number>(9).fill(9)
function a<T> (length: number, value: T) {
const arr = Array<T>(length).fill(value)
}
const res = a<string>(3, 'foo');
类型声明
import { camelCase } from 'loadsh'
declare function camelCase(input: string): string // declare 兼容js 模块
或者安装 @types/lodash 类型声明模块.
query-string 本身带了类型声明.
tsconfig.json
- tsc x.ts -w
- ts配置文件 tsconfig.json 可以写注释的.(通常json文件不能写注释)
{
"include": ["./src/**/*"], // 哪些ts文件需要被编译 * 表示任意文件, ** 表示任意目录
"exclude":[ "node_modules","dist" ],
"extends": "./configs/base" // 继承
"files": [], // 设置编译文件, 通常不用, 因为一个一个写比较麻烦
"compilerOptions": {
"target": "ES6", // 被编译为的ts 版本 ESNext最新的 ES6就是ES2015
"module":"ES2015", // commonjs amd umd
"lib": ["DOM"], // 用到了DOM
"outDir": "./dist", // 编译后的文件位置
"outFile": "" // 合并文件, system, amd模块化才能合并.
"removeComments": true, //
"noEmit": true, // 不生成编译后的js 文件
"noEmitOnError": true // 有错不编译
}
}
webpack打包ts
- npm init -y
- cnpm i -D webpack webpack-cli typescripot ts-loader
- babel 转js 用的, @babel/core @babel/preset-env babel-loader core-js
面向对象
通过对象操作, 就是面向对象. 对象是对现实事物的抽象.(事物有属性和方法)
class A{
id: string = 123;
say() {}
}
B extends A {
constructor(name, age, id) {
super(id) // 手动调用父类的构造函数
super.say() //
}
}