// 安装 Typescript
npm install -g typescript
//使用 tsc 全局命令
tsc -v // 查看 tsc 版本
tsc fileName.ts // 编译 ts 文件
动态类型&静态类型
- 按在什么时候检查数据类型的时机分类,动态在运行时检查数据类型,静态是在编译时候检查数据类型
- 静态语言在编译期间做类型检查,在写代码的时声明变量的类型。比如 java、php、ts 都是静态
- 动态语言在运行期间做类型检查,动态语言不需要指定数据类型。比如 javascript 、python 是动态的。
强类型&弱类型
- 强类型和弱类型按照 是否允许隐式转换 来分类
- 强类型语言 指 强制数据类型定义的语言,某变量被指定某类型,若不经过强制数据类型转换,他永远都是这个数据类型。强类型好处是 严谨、安全。
- 强类型语言 指 数据类型可被忽略,某变量可以赋不同的数据类型的值。好处是 编写代码速度更快更简单。
number
数字类型,包含小数、其他进制的数字
默认十进制,0b表示二进制,0o表示八进制,ox表示十六进制
let num1:number=666.88
let num2:number=0xf00d
let bigNum:bigint=100n
string
字符串
let color:string="blue"
boolean
布尔值
值只能是true或false,不能是0或1
let isDone:boolean=false
any
任何值,不做任何类型检查(不建议使用)
let anySure:any=4
anySure='五六七'
anySure='false'
空值
表示不返回任何值。
一般是用在函数返回类型上,表示没有任何返回值的函数,一般可省略。
只能将它赋值为null或者undefined
function hello():void{
console.log('hello')
}
null
表示不存在的对象值。
使用null关键字定义原始类型,本身无意义。
null一般用来当值,而不是类型使用
null类型可以被赋值为null、undefined、any,其他值不能对其进行赋值
let nv:null=null
let nv1:null=undefined
let nv2:null=2 //报错
undefined
已经声明单位初始化的变量的值。
undefined和null是所有类型的子类型,也就是说他们可以赋值给任何类型的变量
undefined一般用来当值,而不是类型使用
undefined类型可以被赋值为null、undefined、any,其他值不能对其进行赋值
let nv:undefined=null
let nv1:undefined=undefined
let nv2:undefined=2 //报错
never
其他类型的子类型(包括null和undefined),表示不会出现的值
never类型只能赋值给自身,其他类型不能给其赋值,包括any类型
never类型一般出现在函数抛出异常Error存在无法正常结束(死循环)情况下
//返回never的函数
function err(message:string):never{
throw new Error(message)
}
//推断返回值类型为never
function fall(){
return error('Something failed')
}
//返回never函数无法正常结束
function infiniteLoop(){
while(true){
}
}
symbol
es6引入的原始数据类型,表示独一无二的值
symbol类型的变量一旦创建就不可变更,且不能为它设置属性
symbol一般是作为对象的属性
symbol类型的值是通过symbol构造函数进行创建的
let s1=Symbol('name') //Symbol()
console.log(s1) //Symbol(name)
console.log(s1.toString) //"Symbol(name)"
//symbol不可改变且唯一
let s2=Symbol()
let s3=Symbol()
console.log(s2==s3) //false
let s4=Symbol('age')
let s5=Symbol('age')
console.log(s4==s5) //false
//作为对象属性的键
let obj={
[s1]:'小明', //Symbol('name'):'小明'
[s2]:12
sex:'man'
}
symbol类型不能和其他类型进行计算会报错
let s1=Symbol('name')
console.log(s1+'我是symbol') //报错
symbol类型转换
let s1=Symbol('name')
console.log(String(s1)) //'Symbol('name')'
console.log(Boolean(s1)) //true
console.log(Number(s1)) //报错
union
联合类型表示取值可以为多种类型
let a:string|number
a='123'
a=123
//判断类型
function add(x:number|string):number{
if(typeof x==='string'){
//如果是字符串类型
}else{
//如果是数字类型
}
}
类型断言
手动指定一个值的类型
语法规则:
- <类型>值或者对象
- 值或者对象 as 类型
function add(x:number|string):number{
//转换成联合类型中不存在的类型会报错
const str=input as string //告诉ts 我更了解这个类型,就可以使用这个类型的全部方法
}
function getLength(a:number|string):number{
//if(a as string).length(){
if(<string>a).length){
return (<string>a).length
}else{
return a.toString().length
}
}
array
"所以元素类型相同"值的集合
let list:Array<number>=[1,2,3];
let arrOfNum:number[]=[1,2,3];
interface User{
name:string
}
const join={name="john"}
const jack={name="jack"}
类数组
function test(){
// arguments 属于IArguments类型
console.log(arguments) //类似数组,但不是数组 let arr:any[]=arguments 报错
//arguments.length 含有一部分数组的方法
//arguments.forEach 不支持
}
函数
//参数 返回值的类型
const isFalsy=(value:any):boolean=>{
return value?true:false
}
const isFalsy:(value:any)=>boolean=(value)=>{
return value?true:false
}
//没有返回值
const useMount=(fn:()=>void)=>{
useEffect(()=>{
fn();
})
}
object
除了number,string,boolean,bigint,symbol,null,undefined其他都是object
tuple
“数量各异,类型可以各异”的数组
const useHappy=()=>{
return [isHappy,makeHappy,makeUnHappy]
}
const SomeComponent=()=>{
const [tomIsHappy,makeTomHappy,makeTomHappy]=useHappy(false)
}
enum
枚举 对象
//常量 有些范围内的一些系列常量
enum obj{
Up,
Down,
Left,
Right
}
//会自动赋值递增 0123
//赋值的话 Up=10,以此11、12、13
console.log(obj.Up)//0
console.log(obj[0])//'Up'
//字符串枚举
const enum obj{ //加const就是常量枚举
Up='UP',
Down='DOWM',
Left='LEFT',
Right='RIGHT'
}
const value='UP'
if(value===obj.Up){
console.log('go up!')
}
let directions:obj=obj.up
console.log(directions) //UP
null undefined
let u:undefined = undefined;
let u:null = null;
unknown
任何值 unknown是严格班的any
const isFalsy:(value:unknow)=>{
console.log(value.name) //unknown会检验name属性是否存在,而any不做任何检测
}
let value:unknow
value=1
let v=value //报错,不能把unkonwn类型的值赋值给任何值,也不能读取unknow方法
函数
//函数声明
function add(x:number,y:number,z?:number):number{
//z?可选参数,放在参数最后面
//:number 返回数字类型
}
//函数表达式
const add=(x:number,y:number,z?:number):number=>{
//add 函数类型 const add=(x:number,y:number,z?:number)=>number
//:number 返回数字类型
}
let add2:add1=(x:number,y:number,z?:number)=>number=add
//声明函数类型
//冒号后面都是在声明类型
interface Ifun{
(x:number,y:number,z?:number):number
}
let add2:Ifun=add
泛型
function echo<T>(arg:T):T{
//1.T只是泛型的名称,可任意命名
//2.第一个T占位符,可以是任意类型
//3.第二个T参数类型
//4.第三个T返回值类型
return arg
}
//传入什么类型,返回什么类型
const str:string = 'str'
const res=echo(str) //直接填 'str',会进行类型推论
function swap(T,U)(tuple:[T,U]):[T,U]{
return [tuple[0],tuple[1]]
//tuple[0]传入的T类型,tuple[1]传入的U类型
}
const res2=swap(['string',123])
//函数中
function echoWidthArr<T>(arg:T):T{
console.log(arg.length) //会报错,因为不知道类型是什么,不能确定有length方法
return arg
}
//解决办法
interFace IWidthLength{
length:number //只要length属性返回number类型
}
function echoWidthArr<T extends IWidthLength>(arg:T):T{
console.log(arg.length)
return arg
}
echoWidthArr('str')
echoWidthArr({length:3,width:10})
echoWidthArr([1,2,3])
//类中
class Queue<T>{
private data=[];
push(v:T){ //v:number
return this.data.push(v)
}
pop():T{
return this.data.pop(v)
}
}
const q=new Queue
//const q=new Queue<number> 可限制推入的类
q.push('123')
q.pop().toFixed() //pop的事string类型,却调用了数字方法。我们希望push和pop的类型相同
interface keyPair<T,U>{
key:T
value:U
}
let kp1:keyPair<number,string>={key:1,value:'string'}
let kp2:keyPair<string,number>={key:'1',value:6}
let kp3:number[]=[1,2,3]
let kp4:Array<number>=[1,2,3]
d.ts
js文件 + .d.ts 文件 === ts 文件
d.ts文件可以让JS 文件继续维持自己JS文件的身份,而拥有TS的类型保护一般我们写业务代码不会用到,但是点击类型跳转一般会跳转到.d.ts文件
interface
接口,创建自己的类型
interface User{
id:number
readonly name:string; //只能读不能写
}
const u:User={
id:1,
name:'你好',
}
u.name='xxx' //报错
类型别名 type
let sum:(x:number,y:number)=>number
const res=sum(1,2)
//改变后
type PlusType=(x:number,y:number)=>number
let sum1:PlusType
const res=sum2(1,2)
//联合类型
type strNum=string|number
let res1:strNum='123'
res1=123
//内容只能等于类型
const str:'name'='name'
const num3:1=1
//联合类型
type Direction='up'|'Down'|'left'|'right'
let toWhere:Direction='left'//值只能在限定类型中选择
//交叉类型
interface IName{
name:string
}
type Iperson=IName&{age:number}
let person:IPerson={name:'123',age:123}
实用类型
interface IName{
name:string
age:number
}
//Partial可选的
type Ipartial=Partial<IName> //IName里面的内容都变成可选的
//Omit可忽略的,第二个参数是可忽略的内容
type IOmit<Ipartial,'name'> //现在只有age是可选内容
在react中的使用
React.ReactNode 是React框架中的一个类型,它用于表示 React 组件的返回值。它可以是 JSX 元素、字符串