自己常用的 TS 写法总结,应该会一直更新。可使用 TS在线编译 校验 TS 语法。
基本用法 普通 1 2 3 4 5 6 const num : number = 10 const isStop : boolean = false const title : string = '常用TS总结' const curName : null = null const curType : undefined = undefined const birthday : Date = new Date ()
对象 1 2 3 4 5 6 7 8 type LoginParams = { account : string } interface LoginParams { account : string }
不确定是否有此属性用 ?
1 2 3 4 5 6 7 interface Info { id : string name : string birthday?: Date } const curInfo : Info = { id : 'dqe2e' , name : 'weizwz' }console .log (curInfo?.birthday )
数组 1 2 3 const nums : number [] = [1 , 2 , 3 ]const answer : boolean [] = [false , true , false ]const names : string [] = ['w' , 'e' , 'i' ]
对象数组
1 2 3 4 interface Info { id : string } const curInfos : Info [] = [ { id : 'dqe2e' }, { id : 'der24' } ]
函数 函数需要声明参数类型和返回值类型
1 2 3 4 function getWeek (week: string ): string { return '星期' + week }
箭头函数
1 2 3 4 const getWeek = (week : string ): string => { return '星期' + week } console .log (getWeek ('六' ))
没有返回值 用 void
表示
1 2 3 4 5 6 7 interface Cat { weight : 5 } const getName = (obj : Cat ): void => { console .log (obj.weight + '斤' ) } getName ({ weight : 5 })
any类型 any 类型表示没有任何限制,及时后续使用改变了类型也不会报错。但是并不推荐使用 any,否则使用 TS 也失去了意义。
1 2 3 let x : any = 'weizwz' x = 1 console .log (x)
真正的使用场景可能是老项目的升级,你无法确定老旧的代码具体是什么类型;或者一些特殊情况,比如接口返回值类型不确定,或者后续使用时你要修改它的类型。
1 2 3 4 function getStatus (code: any ): Boolean { return (code === '200' || code === 'ok' || code === 200 || code === true ) } console .log (getStatus (400 ))
类型联合 |
某个变量可能是多个类型中的一个,用 |
来分隔
1 2 type Id = string | number type stringBoolean = '1' | '0'
类型交叉 &
类型交叉一般用于多个类型组成的一个新类型,用 &
来连接
1 2 3 4 type Name = { name : string };type User = Name & { age : number };const zhangSan : User = { name : '张三' , age : 18 }
类型断言 手动指定类型,写法是 值 as 类型
或 <类型>值
。 为什么要手动指定类型,是在某些特定情况下,我们已经确定这种类型是可以这样操作,但是编译器不确定,会报错,所以我们使用类型断言去告诉编译器这样做没问题。
1 2 3 4 5 6 7 const $name = document .getElementById ("name" )if ($name) { ($name as HTMLInputElement ).value }
type 和 interface type 命令用来定义一个类型的别名; interface 用来声明对象结构。
区别
type 能表示的任何类型组合; interface 只能表示对象结构的类型
type 后面需要用 =;interface 后面不需要 =
interface 可以继承自(extends)interface 或对象结构的 type;type 可以通过 & 做对象结构的继承
多次声明的同名 interface 会进行声明合并;type 不允许多次声明,一个作用域内不允许有多个同名 type
示例 type
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 type stringBoolean = '1' | '0' type Position = { x : number y : number } type Position3D = Position & { z : number }const startPosition : Position = { x : 0 , y : 10 }const startPosition3D : Position3D = { x : 0 , y : 10 , z : 20 }type Position = { z : number }
interface
使用
1 2 3 4 5 6 7 interface Position { x : number }interface Position { y : number }const startPosition : Position = { x : 0 , y : 10 }interface Position { x : string }
继承扩展
1 2 3 4 5 interface Position3D extends Position { z : number } const startPosition3D : Position3D = { x : 0 , y : 10 , z : 20 }
泛型 泛型一般用 T 表示,表示其中的参数/属性/返回值可以是任何类型,如果有多个泛型,可以使用其他字母。 主要使用场景:有些对象中的属性,或者方法里的参数,可能有多个类型,具体类型根据使用场景来定。
基础使用 1 2 3 4 type Empty <T> = T | undefined | null const noData : Empty <[]> = []
多个泛型
1 2 3 4 5 6 7 8 interface Info <T, S> { name : string types : T[] weight : S } const tom : Info <string , number > = { name : 'tom' , types : ['cat' , 'animal' ], weight : 5 }const idx : Info <number , string > = { name : 'idx' , types : [1 ], weight : 'first' }
函数 1 2 3 4 function getFirst<T>(arr : T[]): T { return arr[0 ] }
箭头函数 <T,>
加逗号是为了避免编译程序把 <>
解析成 jsx
1 2 3 4 5 6 const getFirst = <T,>(arr : T[]): T => { return arr[0 ] } const arr : number [] = [1 , 2 , 3 ]console .log (getFirst<number >(arr), getFirst (arr))
嵌套 使用嵌套可以提供代码复用率,如果类型之间差别点太多就没必要了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 interface Tom <T> { name : string type : T } interface People { name : string type : 'person' } interface Cat { name : string type : 'animal' } const myBrother : Tom <People > = { name : 'jakeTom' , type : { name : 'my brother' , type : 'person' } } const myCat : Tom <Cat > = { name : 'catTom' , type : { name : 'cat' , type : 'animal' } }
特殊用法 动态变量名 Record<Keys, Type>
返回一个对象类型,参数 Keys
用作键名,参数 Type
用作键值类型。
1 2 3 4 5 6 7 8 9 type stringKey = Record <string , string >const list : stringKey = { img_1 : 'img/1.png' , img_2 : 'img/2.png' , img_3 : 'img/3.png' }for (const key in list) { console .log (list[key]) } for (let i = 0 ; i < 3 ; i++) { console .log (list['img_' + (i + 1 )]) }
vue3中的TS 响应式数据 在 xxx.d.ts
里定义类型
1 2 3 4 interface Account = { id : string name : string }
在 vue 界面里使用
1 2 3 4 5 6 const loading = ref (false )const user = ref<Account >({ id : 'E2U1EU91U' , name : 'weiz' })
参数传递 父组件使用
1 2 3 4 5 6 7 8 9 10 <script setup lang ="ts" > import { ref } from 'vue' const user = ref<Account >({ id : 'E2U1EU91U' , name : 'weiz' }) </script > <template > <Children :account ="user" > </template >
子组件接收参数
1 const props = defineProps<Account >()
如果没有声明 Account
,则可以具体定义
1 2 3 4 const props = defineProps<{ id : string name : string }>()
组件实例类型 InstanceType<T>
是 ts 自带的类型,能够直接获取组件完整的实例类型。
子组件
1 2 3 4 5 6 7 <script setup lang ="ts" > const open = ( ) => { console .log ('打开' )}defineExpose ({ open }) </script >
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <script setup lang ="ts" > import { ref } from 'vue' import Children from './Children.vue' type ChildCtx = InstanceType <typeof Children > const childrenRef = ref<ChildCtx | null >(null )const openChildren = ( ) => { childrenRef.value ?.open () } </script > <template > <Children ref ='childrenRef' /> </template >