<div id="content_views" class="htmledit_views">
<blockquote>
TypeScript是拥有类型的JavaScript超集,它可以编译成普通、干净、完整的JavaScript代码。我们可以将TypeScript理解成加强版的JavaScript。
简单来说:Ts是带类型语法的Js; Ts是Js的超集
TS官方网站:https://www.typescriptlang.org/
TS中文官网:https://www.tslang.cn/
一、基础语法
js已有类型:
基本类型: number, string, boolean, null, undefined, symbol,BigInt
引用数据类型:对象、数组、函数
ts新增类型:
联合类型、类型别名、接口、元祖、字面量类型、枚举、void、any、泛型等
(一) 原始类型
1.简单类型 :xx
-
let
age:
number =
18;
-
-
let
uname:
string =
"zhangsan";
-
-
let
flag:
boolean =
false;
-
-
// null和und类型用的比较少
-
-
let
nullValue:
null =
null;
-
-
let
undefinedValue:
undefined =
undefined;
PS:其实最后.ts转为.js文件时void仍会变为undefined,TS中加上void一般只是为了将函数返回值和其他区分出来。
2.引用类型 :xx[]
a.数组
-
let arr1 = [
"a",
"b",
"c"]
-
-
let
arr3:
number[] = [
1,
2,
3]
-
-
let
arr2:
string[] = [
"a",
"b",
"c"]
-
-
console.
log(arr1, arr2, arr3);
-
-
-
-
let
arr4:
Array<
string> = [
"ok",
"hello"]
-
-
console.
log(arr4);
思考:数组中是可以存放多种数据类型
联合类型:|(竖线)在TS中叫做联合类型
即:由两个或多个其他类型组成的类型,表示可以是这些类型中的任意一种
b.函数
-
// 函数 给参数和返回值 指定类型
-
-
// 函数声明(具名函数)
-
-
function
add(
a: number, b: number):
number {
-
-
return a + b
-
-
}
-
-
console.
log(
add(
1,
2));
-
-
-
-
// 函数表达式(匿名函数)
-
-
let add2 = (
a:
number,
b:
number):
number => {
-
-
return a + b
-
-
}
-
-
console.
log(
add2(
1,
2));
-
-
-
-
// 箭头函数写法
-
-
type
AddFn =
(a: number, b: number) =>
number
-
-
// 通过类似箭头函数形式的语法为函数添加类型,只适用于函数表达式
-
-
let
add3:
AddFn =
(a, b) => {
-
-
return a + b
-
-
}
-
-
console.
log(
add3(
3,
3));
可选参数:?
使用 ? 将参数标记为可选
const fn = (n?: number) => {
}
fn()
fn(1)
函数返回值:
在js中默认返回值是und,在ts中默认返回的是void
如果指定返回值类型是 undefined 那返回值一定是 undefined
-
// void和undfined类型
-
-
// 如果函数没有返回值,定义函数类型时返回值的类型为void
-
-
const
say = (
) => {
-
-
// console.log('hello ts~');
-
-
}
-
-
console.
log(
say());
-
-
console.
log(
typeof
say());
-
-
const say2 = ():
void => {
-
-
// console.log('hello ts~');
-
-
}
-
-
console.
log(
say2());
-
-
console.
log(
typeof
say2());
-
-
// 区分:在js中默认返回值是und,在ts中默认返回的是void
-
-
// 如果指定返回值类型是 undefined 那返回值一定是 undefined
-
-
const say3 = ():
undefined => {
-
-
// console.log('hello ts~');
-
-
}
-
-
console.
log(
say3());
-
-
console.
log(
typeof
say3());
c.对象
-
// 空对象
-
-
let obj1 = {}
-
-
let
obj2: {} = {}
-
-
-
-
// 指定对象里面的属性和方法
-
-
// let obj4: { name: string, say(): void } = {
-
-
let
obj4: {
name:
string;
say():
void } = {
-
-
name:
"wc",
// 对象里面写方法的两种写法 // say():void say: () => void
-
-
}
-
-
// 竖着写 可以换行
-
-
let
obj5: {
-
-
// name: string,
-
-
name:
string;
-
-
say():
void
-
-
} = {
-
-
name:
"wc",
-
-
say(
) { }
-
-
}
(二) 类型别名 type
给某个指定类型起别名
定义类型别名,遵循大驼峰命名,类似于变量
什么时候是用类名别名?
当同一类型(引用)被多次使用,可以通过类型别名简化
-
// 语法:type 类型别名=具体类型
-
-
type A = (
string |
number)[]
-
-
let
arr9: A
-
-
arr9 = [
1,
"a",
3]
交叉类型 &
-
// type 交叉类型
-
-
type
APoint2D = {
-
-
x:
number,
-
-
y:
number
-
-
}
-
-
-
-
type
APoint3D =
APoint2D & {
-
-
z:
number
-
-
}
-
-
-
-
let
o:
APoint3D = {
-
-
x:
1,
-
-
y:
2,
-
-
z:
3
-
-
}
(三) 接口 interface (可继承extends)
interface 后面跟的是接口名称
注意:接口的每一行只能有一个属性或者一个方法 每一行不需要加分号
interface Person {
name: string
age: number
say: () => void
}
-
let
p:
Person = {
-
-
name:
"wangcai",
-
-
age:
18,
-
-
say(
) { }
-
-
}
-
-
console.
log(p);
-
-
-
-
// 接口是可继承的
-
-
// 2D坐标
-
-
interface
Point2D {
-
-
x:
number
-
-
y:
number
-
-
}
-
-
let
p2:
Point2D = {
-
-
x:
1,
-
-
y:
2
-
-
}
-
-
console.
log(p2);
-
-
-
-
// 如何实现继承?
-
-
// 使用extends实现接口继承,达到类型复用
-
-
-
-
// 继承后 接口A 拥有了接口B的所有属性和函数的类型声明 interface Point3D extends Point2D { z: number}
-
-
-
-
let
p3:
Point3D = {
-
-
x:
1,
-
-
y:
2,
-
-
z:
3
-
-
}
(四)interface和type的区别
1.type是起别名,interface 是自己发明类型 自定义类型
-
// 会报错
-
-
// type APerson = {
-
-
// name:string
-
-
// }
-
-
// type APerson = {
-
-
// age:number
-
-
// }
-
-
-
-
interface
Person1 {
-
-
name1:
string
-
-
};
-
-
interface
Person1 {
-
-
age1:
number
-
-
};
-
-
// 类型合并
-
-
const
c1:
Person1 = {
-
-
name1:
"wc",
-
-
age1:
18
-
-
}
2.type不可以重复定义,interface可以重复定义会合并
3.type支持对象类型和其他类型,interface只支持对象类型
4.type复用:交叉类型 &,interface复用:可以继承 extends
二、ts在vue3中的使用
(一)ref和ts
// 手动指定类型
const count =ref<number>(0)
-
<template>
-
-
<div>{{ count }}
</div>
-
-
<ul>
-
-
<li v-for="item in list" :key="item.id">
-
-
{{ item.name }}
-
-
</li>
-
-
</ul>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { ref, reactive }
from
"vue"
-
-
-
-
// 手动指定类型const count =ref<number>(0)
-
-
-
-
// 自动类型
-
-
const count1=
ref(
0)
-
-
-
-
type
ToDoItem={
-
-
id:number;
-
-
name:string;
-
-
done:boolean
-
-
}
-
-
// [{},{},{}]
-
-
const list=ref<
ToDoItem[]>([])
-
-
-
-
setTimeout(
()=>{
-
-
list.
value=[
-
-
{
id:
100,
name:
"吃饭",
done:
false },
-
-
{
id:
101,
name:
"睡觉",
done:
false },
-
-
]
-
-
},
1000)
-
-
</script>
(二)reactive和ts
type Book={
title:string;
year?:number
}
const book:Book=reactive({
title:"ts语法基础"
})
-
<template>
-
-
{{ book.title }} -- {{ book.year }}
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { ref, reactive }
from
"vue"
-
-
-
-
// 1.手动指定类型
-
-
type
Book={
-
-
title:string;
-
-
year?:number
-
-
}
const
book:
Book=
reactive({
-
-
title:
"ts语法基础"
-
-
})
-
-
book.
year=
2023
-
-
-
-
// 2.自动类型推导
-
-
const
Book=
reactive({
title:
"ts语法基础2"})
-
-
</script>
(三)computed和ts
const doubleCountB = computed<string(() => (count.value * 2).toFixed(2))
-
<template>
-
-
{{ count }} -- {{ doubleCount }} -- {{ doubleCountB }}
-
-
{{ typeof count }} -- {{ typeof doubleCount }} -- {{ typeof doubleCountB }}
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { ref, computed }
from
"vue"
-
-
const count =
ref(
205)
-
-
-
-
// 1.自动类型推导
-
-
// toFixed(2)保留2位小数,且返回值类型为string
-
-
const doubleCount =
computed(
() => (count.
value *
2).
toFixed(
2))
-
-
// 2.指定计算属性的类型
-
-
const doubleCountB = computed<string>(
() => (count.
value *
2).
toFixed(
2))
-
-
</script>
(四)defineprops和ts(父传子)
defineProps<{
money:number;
car?:string
}>()
Child.vue
-
<template>
-
-
<div class="">
-
-
<p>{{ money }}
</p>
-
-
<p>{{ car }}
</p>
-
-
</div>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
// vue3基本写法
-
-
// defineProps({
-
-
// money:{
-
-
// type:Number,
-
-
// required:true
-
-
// }
-
-
// })
-
-
-
-
// ts基本语法
-
-
// defineProps<{
-
-
// money:number;
-
-
// car?:string
-
-
// }>()
-
-
-
-
// ts+有默认值的写法
-
-
withDefaults(
-
-
defineProps<{
-
-
money:number;
-
-
car?:string
-
-
}>(),{
-
-
money:
666,
-
-
car:
"xiaomi"
-
-
}
-
-
)
-
-
</script>
App.vue
-
<template>
-
-
<div>
-
-
<!-- 父传子 -->
-
-
<Child :money="money">
</Child>
-
-
</div>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { ref}
from
"vue"
-
-
import
Child
from
"./components/Child.vue"
-
-
const money=
ref(
666)
-
-
const car=
ref(
'大众')
-
-
</script>
(五)defineEmits和ts(子传父)
const emit =defineEmits<{
(e:"changeMoney",money:number):void;
(e:"changeCar",car:string):void;
}>()
Child.vue
-
<template>
-
-
<p>{{ money }}
</p>
-
-
<button @click="emit('changeMoney', 800)">改money
</button>
-
-
<p>{{ car }}
</p>
-
-
<button @click="emit('changeCar', '宝马')">改car
</button>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
// vue3基本写法
-
-
// const emit = defineEmits(["changeMoney", "changeCar"])
-
-
-
-
// ts写法
-
-
defineProps<{
-
-
money: number;
-
-
car?: string;
-
-
}>()
-
-
const emit =defineEmits<{
-
-
(
e:
"changeMoney",
money:number):
void;
-
-
(
e:
"changeCar",
car:string):
void;
-
-
}>()
-
-
</script>
App.vue
-
<template>
-
-
<!-- 子传父 -->
-
-
<Child
-
-
:money=
"money"
-
-
:car=
"car"
-
-
@
change-money=
"money=$event"
-
-
@
change-car=
"car=$event"
-
-
>
</Child>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { ref}
from
"vue"
-
-
import
Child
from
"./components/Child.vue"
-
-
const money=
ref(
666)
-
-
const car=
ref(
'大众')
-
-
</script>
(六)事件处理和ts :Event
as 断言
e:Event
-
<template>
-
-
<input type="text" @change="handleChange" value="hi">
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
// 不处理类型
-
-
// const handleChange=(e)=>{
-
-
// console.log(e.target.value)
-
-
// }
-
-
-
-
const
handleChange=(
e:Event)=>{
-
-
// as 断言
-
-
// e.target 事件源
-
-
console.
log((e.
target
as
HTMLInputElement).
value);
-
-
}
-
-
</script>
(七)ref写在标签上获取 :HTMLInputElement
const input = ref<HTMLInputElement | null(null)
-
<template>
-
-
<div>
-
-
<input type="text" ref="input">
-
-
</div>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { onMounted, ref }
from
'vue'
-
-
const input = ref<
HTMLInputElement |
null>(
null)
-
-
-
-
// 页面加载完毕调用钩子函数
-
-
onMounted(
()=>{
-
-
input.
value?.
focus()
-
-
})
-
-
</script>
(八)非空断言 !
// ! 非空断言(方法一)
input.value!.value = "456" //可以赋值
// 类型守卫(方法二)
if (input.value) {
input.value.value = "789" //可以赋值
}
-
<template>
-
-
<div>
-
-
<input type="text" ref="input" value="123">
-
-
</div>
-
-
</template>
-
-
-
-
<script setup lang="ts">
-
-
import { onMounted, ref }
from
'vue'
-
-
const input = ref<
HTMLInputElement |
null>(
null)
-
-
-
-
// 页面加载完毕调用钩子函数
-
-
onMounted(
() => {
-
-
// 自动获取焦点
-
-
input.
value?.
focus()
-
-
// 使用ES6 输入框没有获取到,对于可能出现null,
-
-
console.
log(input.
value?.
value);
-
-
// ?可选参数 可选链 报错 因为不能赋值
-
-
// input.value?.value = "456"
-
-
-
-
// ! 非空断言(方法一)
-
-
input.
value!.
value =
"456"
//可以赋值
-
-
// 类型守卫(方法二)
-
-
if (input.
value) {
-
-
input.
value.
value =
"789"
//可以赋值
-
-
}
-
-
})
-
-
</script>