一、TypeScript安装
npm install -g typescript
查看版本
tsc -v
二、TypeScript如何编译
tsc hello.ts
文件ts为后缀
三、TypeScript的使用
TypeScript为强类型,可以对类型注解、添加类型约束
1.原始类型 完全按照js中类型名称来书写的(js已有类型)
let age:number = 18
let myName: string = '刘老师'
let isLoading: boolean = false
let a: null = null
let b: undefined = undefined
let s: symbal = Symbol()
2.引用类型 object(包括数组、对象、函数等)
- 数组类型 :TypeScript中更加细化 每个具体对象都有自己类型的语法
let numbers: number[] = [1,2,3]
let string: Array<string> = ['a','b','c']
let b:boolean[] = [true,false]
- 函数指定类型和返回类型
function add(num1:number,num2:number):number{
return num1+num2
}
cosnt add = (num1: number,num2:number):number=>{
return num1+num2
}
add(1,2)
const add:(num1: number,num2:number)=>number = (num1,num2) => {
return num1+num2
}
- 函数没有返回值 void
function greet(name: string): void{}
- 函数类型可选参数,
注意:可选参数在必选参数后
function mySlice(start?: number, end?:number):void{
}
- 泛型,在使用的时候指定类型
//方式1
let f = function<T>(v1:T,v2:T):boolean {}
f<string>('a','b')
//方式2-1
interface IFunc { //对函数参数类型进行检查
(v1:string,v2:string):boolean
}
let f2: IFunc = function (v1,v2){
return v1 === v2
}
interface IFunc2 { //接口中也可使用泛型
<T>(v1:T,v2:T):boolean
}
let f3: IFunc2 = function (v1,v2){
return v1 === v2
}
f3<number>(2,3)
//方式2-2
interface IFunc2<T> { //接口中也可使用泛型
(v1:T,v2:T):boolean
}
let f3: IFunc2<number> = function (v1,v2){
return v1 === v2
}
f3(2,3)
- 对象类型
sayHi()=>void
- 多行形式可以省略分号(如果一行代码只指定一个属性类型)
let person: {name: string;age: number;sayHi(): void;greet(name: string): void} = {
name:'jack',
age:20,
sayHi() {},
greet(name) {}
}
- 可选属性
function myAxios(config: { url: string; method?: string}){
console.log(config)
}
3.TypeScript新增类型(类型推断):
联合类型、自定义类型(类型别名)、接口、
元组、字面量类型、枚举、void、any等
- 联合类型
let arr: (number | string)[] = [1,2,3,'ww']
- 定义类型
type customarr = (number | string)[]
let arr1: customarr = [1,'2',3]
let arr2: customarr = [1,'5',3]
- 接口 interface 来描述对象类型达到可以复用的目的,
规范:接口首字母大写 I
interface IPerson{
name: string
age:number
sayHi(): void
}
let person: IPerson = {
name: '刘老师',
age:18,
sayHi() {}
}
- 接口可选属性
interface IPerson{
name: string
age?:number //可选属性,可有可无
sayHi(): void
[propName: string]:any; //任意属性
}
interface Point2D {
x: number; y:number
}
interface Point3D extends point2D{
z:number
}
let p3: Point3D = {
x:1,
y:0,
z:1
}
- 任意属性,一旦定义,那么确定属性和可选属性都必须是它的子属性 使用 继承 实现复用
- 元组 确切地知道包含多少个元素,以及特定索引对应的类型
let position: [number, number] = [999,888]
- 断言
const aLink = document.getELementById('link) as HTMLAnchorElement
第二种写法
const aLink = <HTMLAnchorElement>document.getElementById('link')
aLink.href
- 字面量类型 适用于确定类型,一般配合联合类型使用
let str1 = 'hello Ts' 类型string
let str2 = 'Hello Ts' 类型Hello Ts
- 枚举 可设置初始值
emum Direction {Up=10, Down, Left, Right}
function changeDirection(direction: Direction){
}
changeDirection(Direction.Up)
- 字符串枚举 没有自增长行为,每个都必须有初始值
emum Direction {Up='Up', Down='Down', Left='Left', Right='Right'}
- any类型 不推荐使用 使用后会变成AnyScript 失去TS类型保护优势
let obj: any = { x: 0 }
- typeof操作符 可以在类型上下文中引用变量或属性的类型
let p = {
x: 1,
y: 2
}
function formatPoint(point: typeof p){
}
formatPoint({x:1, y:100})
4.TypeScript中的高级类型:class类、类型兼容性
- class类,添加了类型注解和其他语法 不仅提供了语法功能,也作为一种类型存在
class Person{
age: number
gender = '男'
}
const p = new Person()
// - 构造函数 没有返回值
class Person {
age: number
gender: string
constructor(age:number,gender: string) {
this.age = age
this.gender = gender
}
}
new Person(18,'nan')
- 实例方法
class Point {
x = 1
y = 10
scale(n:number){
this.x *= n
this.y *= n
}
}
const p = new Point()
p.scale(10)
- 继承
class Animal {
move(){
console.log('moving along')
}
}
class Dog extends Animal{
}
- 实现接口
interface Singable {
sing(): void
}
class Person implements Singable{
nsme = 'jack'
sing(){
console.log('小盘股)
}
}
- ts可以使用控制class的方法或者属性对于class外的代码是否可见。public 公共成员可以被任何地方访问,默认可见性
class Animal {
public move(){
console.log('moving')
}
}
- protected(受保护的) 仅对其所在声明所在的类和子类中(实例对象)可见
- private 私有 只能在当前类调用
- readonly 只能修饰属性 只读用来防止在构造函数之外对属性进行赋值
class Person{
readonly age: number = 28
constructor(age: number) {
this.age = age
}
setAge(){
}
}
- 类型兼容性
let arr = ['a','b','c']
arr.forEach(item => {})
- 结构化类型系统
class Point { x:number; y:number }
class Point { x:number; y:number }
const p: Point = new Point2D()
- 成员多的可以赋值给少的
- 接口兼容性
- 函数兼容性:需要考虑 参数个数 参数类型 返回值类型
参数少的可以赋值给参数多的
type F1 = (a: number) => void
type F2 = (a: number,b: number) => void
let f1: F1
let f2: F2
f2 = f1
相同位置的参数类型要相同或兼容,返回值类型 只关注返回值类型本身
- 交叉类型 用于组合多个类型为一个类型
interface Person { name: string }
interface Contact { phone: string }
type PersonDetail = Person & Contact
let obj: PersonDetail = {
name:'jack',
phone:'12333'
}
交叉类型(&)和接口继承(extends) 对于同名属性,处理类型冲突的方式不同
-
泛型 Type:类型变量
实现了复用保证了安全
function id<Type>(value: Type): Type {
return value
}
id<number>(1)
id<string>('a')
//简化调用
let num1 = id(100)
指定更加具体的类型
function id<Type>(value: Type[]): Type[] {
console.log(value.length)
return value
}
添加约束
interface ILength { length:number }
function id<Type extends ILength>(value: Type): Type{
value.length
return value
}
id(['a','c'])
id('abc')
- 泛型类型的变量可以有多个,并且类型变量之间还可以约束
function getProp<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key]
}
let person ={
name: 'jack'
age:18
}
getProp(person,'name')
泛型接口
interface IdFunc<Type> {
id: (value: Type)=> Type
ids: ()=> Type[]
}
let obj: IdFunc<number> = {
id(value) {
return value
}
ids() {
return [1,3,4]
}
}
-
数组是泛型接口
-
泛型类:class也可以配合泛型来使用
class GenericNumber<NumType>{
defaultValue: NumType
add: (x: NumType,y: NumType)=> NumType
constructor(value: NumType) {
this.defaultValue = value
}
}
const myNum = new GenericNumber<number>()
myNum.defaultValue = 10
// 有上面constructor 可以不指定类型
const myNum = new GenericNumber(100)
- 泛型工具类型
Partial<Props>
interface Props{
id: string
children: number[]
}
type PartialProps = Partial<Props>
let p1: Props = {
id: '',
childen: [1]
}
let p2: PartialProps = {
id: ''.
children: [1,3]
}
- 泛型工具类型
Readonly<Type> 构造一个类型只读,不能再改变属性
type ReadonlyProps = Readonly<Props>
let p1: ReadonlyProps = {
id:'1',
children:[1,3]
}
p1.id = '2' 报错
- 泛型工具类型
Pick<Type,Keys> 从Type中选择一组属性来构造新类型
interface Props {
id: string
title: string
children: number[]
}
type PickProps = Pick<Props,'id' | 'title'>
- 泛型工具类型
Record<Keys, Type> 构造一个对象类型
,属性键为Keys,属性类型为Type
type RecordObj = Record<'a' | 'b' | 'c', string[]>
let obj:RecordObj = {
a:['1'],
b:['1'],
c:['1']
}
都是对象类型的数组
- 索引签名类型:当无法确定对象中有哪些属性(或者说对象中可以出现多属性)
// key只是占位符,可以是任意值
interface AnyObject {
[key: string]: number
}
let obj: AnyObject = {
a:2,
b:1
}
- 映射类型: 基于旧类型创建新类型(对象类型),减少重复、提升开发效率
type PropsKeys = 'x' | 'y' | 'z'
type Type2 = {
[Key in PropsKeys]: number
}
keyof
type Props = {a: number, b: string,c: booolean}
type Type3 = { [key in keyof Props]: number}
泛型工具类型都是基于映射类型实现的
比如 Partial的实现
type Partail<T> = {
[P in keyof T]?: T[P]
}
type Props = { a: number; b:string; c:boolean}
T[P]在ts中叫做索引查询(访问类型)
type pROPS = { a: number; b: string; c: boolean }
type TypeA = number
type TypeA = Props['a']
- 索引查询类型:同时查询多个索引的类型
type Props = { a: number; b:string; c:boolean }
type TypeA Props['a' | 'b']
typeA = Props[keyof Props]
5.类型声明文件概述
类型声明文件:用来为已存在的js库提供类型信息
-
ts中的两种文件类型
-
.ts 包含类型声明也可包含可执行代码
-
.d.ts 类型声明文件
使用已有的类型文件声明文件
-
内置类型声明文件
所有标准化内置API都提供了声明文件
-
第三方库的类型声明文件
创建自己的类型声明文件
-
项目内共享类型
多个.ts都用到同一个类型
-
为已有文件提供类型申明
-
-
export/import
类型声明文件的编写与模块化方式相关
-
declare 为已存在变量提供类型
可用赋默认值