目录
变量声明
string类型
number类型
boolean类型
Array类型
Object类型
symbol类型
null与undefined类型
any类型
unknown类型
void类型
never类型(了解)
tuple类型
函数的参数与返回值
对象类型
可选类型 ?
联合类型 |
类型别名 type
接口interface
交叉类型 &
类型断言 as
非空类型断言 !
可选链
??与!!运算符
字面量类型
字面量推理
在ts中定义变量需要指定标识符类型,
var/let/const 标识符: 数据类型 = 赋值
当我们没有写数据类型时,ts也会帮助我们进行类型推断,但是能写还是要写的
// let进行类型推导,推导出来的是通用类型
// const 进行类型推导,推导出来的是字面量类型
let age = 18
age = 19
const name = 'zhao'
name = 'yun' //报错
// string 小写 ts中字符串类型
// String 大写 js中包装类
// 支持模板字符串拼接
const message: string = "hello ts"
// 不区分整形与浮点型,ts也支持二进制,八进制,十六进制
let age: number = 18
// 只有true false
let bol: boolean = true
// 数组存放元素要确定,
// 存放不同类型是不好习惯
const names: Array = [] // 不推荐 jsx中有冲突
const names2: string[] = [] // 推荐
// Object类型
// 不要info: Object这样写 之后取值时报错
// 一般都是让它类型推导
const info: Object = {
name: 'yun',
age: 18
}
// 用的较少
const title1: symbol = Symbol('title')
const title2: symbol = Symbol('title')
const youInfo = {
[title1]: "程序员",
[title2]: "教师"
}
// null类型只有一个值 null
const n1: null = null
// undefined类型只有一个值 undefined
const n2: undefined = undefined
// 当我们无法确定变量类型,且它可能变化,我们可以使用any
// 我们可以对any类型的变量进行任何操作
// 如果你项目中所有地方都使用any,则与js没有区别
let message: any = "hello"
message = 123
message = {
}
const arr: any[] = ["shi", 18, 18]
// 用于描述类型不确定的变量
// 与any的区别: any声明的变量可以赋值给任意变量,unknown只能赋值给unknown与any
// 在any上进行任何操作都是合法的
// 在unknown上进行任何操作都是不合法的,必须进行类型缩小
let res: unknown
let fiag = true
if (fiag) {
res = "str"
} else {
res = 123
}
// void通常指定一个函数是没有返回值的,那它的返回值就是void类型
// 我们可以将null undefined赋值给void类型,也就是函数可以返回null与undefined
function sum(num1: number, num2: number): void {
console.log(num1 + num2);
}
// 最常写的方式
// 定义要传入的函数类型
type ExecFnType = (...args: any[]) => void
// 当基于上下文的类型推导,当推导出的类型为void时,并不会强制函数一定不能返回内容
const names = ['zhang','li']
names.foreach(()=>{
return 123 // 不报错,可以这样写
})
// 应用场景 react中usestate函数
// 在函数中使用元组类型是最多的(函数的返回值)
function useState(initValue: number): [number, (newValue: number)=>void]{
let stateValue = initValue
function setValue(newValue: number) {
stateValue = newValue
}
return [stateValue, setValue]
}
// 函数的返回值类型一般不写
function sum(num1: number, num2: number): number {
return num1 + num2
}
const names = ["shi", "yun", "ya"]
// 匿名函数,称之为上下文类型,ts会自动推断item类型
names.map(item => {
})
function friendInfo(friend: {name: string,age: number}) {
console.log(friend.name,friend.age);
}
friendInfo({name:"yun",age:123})
// 可选类型,可选可不选,如果没指定类型,就是any类型
function friendInfo(friend: {name: string,age: number,mom?: string}) {
console.log(friend.name,friend.age);
}
friendInfo({name:"yun",age:123})
friendInfo({name:"ya",age:100,mom:'zhao'})
ts允许我们使用多种运算符从现有类型中构建新类型
联合类型是由两个或者多个其他类型组成的类型; 表示可以是这些类型中的任何一个值
function printInfo(message: number|string|boolean) {
}
printInfo(123)
printInfo("abc")
printInfo(false)
// 联合类型与可选类型关系,可选类型可以看做是类型与undefined的联合类型
function printMes(message?: string) {
}
printMes("xxx")
printMes()
printMes(undefined)
当我们某些类型会重复使用时,我们可以抽取出来,设置类型别名
type IdType = number | string | boolean
function printId(id: IdType) {
console.log(id);
}
printId(1)
printId("22")
printId(false)
// 前面我们是用type声明对象类型
type point1 = {
x: number,
y: number,
z?: number
}
// 我们也可以用接口来声明
interface point2{
x: number,
y: number,
z?: number
}
// type别名与interface接口区别
// 1.type可以声明多种类型,interface只能声明对象
type IdType = string|number
// 2.type别名不能重复,interface可以
interface person{
name: string,
age: number
}
interface person{
height: number
}
const xiaoming: person = {
name: 'zhao',
age: 18,
height: 1.88
}
// 3.interface支持继承
interface animal{
name: string
eat: boolean
}
interface dog extends animal {
run: boolean
}
const mydog: dog = {
name: 'xiaohua',
eat: true,
run: true
}
// 4. interface可以被类实现(以后讲)
// 总结: 定义对象类型推荐interface,其他类型type
我们通常是对对象类型进行交叉
// 交叉类型 两种或多种类型要同时满足
type NewType = number & string // 这是没有意义的
// 常见使用方式
interface Ikun{
name: string,
age: number
}
interface Coder{
name: string,
coding: ()=>void
}
const info: Ikun & Coder = {
name: 'zhao',
age: 18,
coding: ()=>{
console.log("coding")
}
}
TypeScript只允许类型断言转换为 更具体 或者 不太具体 的类型版本,此规则可防止不可能的强制转换
class Person {
}
class Student extends Person {
study() {
console.log("学生学习");
}
}
function fun(item: Person) {
(item as Student).study()
}
const stu1 = new Student()
fun(stu1)
// 不建议的做法
const message: string = "hello"
const num1: number = (message as any) as number
还有一个较多的应用场景是js获取dom元素,比如getElementById()ts显示是HTMLElement对象,可以使用断言,断言成具体的,从而添加属性或使用方法
! 表示可以确定某个标识符是有值的,跳过ts在编译阶段对他的检测
// 这种情况下是编译阶段报错的
function printMes(message?: string) {
// console.log(message.length);
}
// 使用非空断言 !
function printMes2(message?: string) {
console.log(message!.length);
}
printMes2("xxx")
es11新增特性,非ts独有
当获取对象某个属性时,为undefined就短路,后面不执行了,返回undefined,存在就继续运行
type Person = {
name: string,
friend?: {
name: string,
age: number
}
}
const info: Person = {
name: "yun"
}
console.log(info.name);
// info.friend是可选的,存在undefined的情况,使用可选链,没有值就短路,返回undefined
console.log(info.friend?.name);
js的特性,并非ts语法
// !!
// js的特性,一个!是非操作,相当于把一个值变为布尔类型并取反,所以两个!就算是把一个值变为布尔类型
const message: string = "shi yun ya"
const flag: boolean = !!message
console.log(flag);
// ??
// 逻辑操作符 ??左侧有值就使用左侧的值,没值就使用右侧的值
const bol: string = message??""
console.log(bol);
除了前面所示类型,我们还可以使用字面量类型,字面量类型顾名思义就是以值为类型,所以必须与值保持一致
意义:与联合类型使用,可以把范围锁更小
// const message = "shi yun ya"
let message: "shi yun ya" = "shi yun ya"
// message = "hahaha" 报错
// 应用场景,align只能选择声明的四个值
let align : 'left'|'right'|'top'|'bottom' = 'left'
align = 'right'