文章记录编写了ts中涉及的基础知识,包含常用类型、类、函数、泛型等内容。同时按照vue3官方文档结合TypeScript + setup做vue3相关类型标注的举例。
let str: string = 'hello world' // 字符串
let count: number = 100 // 数字
let id:string = 1 // 字符串或数字
let flag: boolean = true // 布尔
let a: null = null // null
let b: undefined = undefined // undefined
在ts中不能为已知类型的变量赋值不同类型:
str = 100 // 该行报错:不能将类型"number"分配给类型"string"
let arr: string[] = ['a','b','c']
let arr2: Array<string> = ['a', 'b', 'c']
let tuple: [string,number,number[],boolean?] = ['a',1,[1,2]]
tuple = ['a', 1, [1, 2],true]
const obj: {
name: string,
age: number,
} = {
name: "LiHua",
age: 18,
};
// 解构形参的类型标注
function fun({ name, age }: { name: string, age: number }) {
console.log(`${name}-${age}`);
}
let id: any = 1
id = 'a'
id = [123, 'a']
console.log(id.length);
let id2: unknown = [1,2]
console.log(id2.length); //改行报错:对象的类型为 "unknown"。
enum Status {
LiHua,
XiaoHong,
XiaoMing,
}
console.log(Status.LiHua); // 0
console.log(Status[1]); // XiaoHong
或者
enum Status {
LiHua = 1,
XiaoHong,
XiaoMing,
}
console.log(Status.LiHua); // 1
console.log(Status[1]); // LiHua
function api(url: string, method: 'GET' | 'POST') {
// ...
}
api('https://123.com', 'GET');
api('https://123.com', 'PUT'); // 报错:类型“"PUT"”的参数不能赋给类型“"GET" | "POST"”的参数。
场景一:
function fail(msg:string):never {
throw Error(msg)
}
场景二:
function request(method: 'get' | 'post') {
switch (method) {
case "get":
return 'get...';
case "post":
return 'post...';
default:
const _exhaustiveCheck: never = method;
return _exhaustiveCheck;
}
}
当 method 增加一个值时:
function request(method: 'get' | 'post' | 'put') {
switch (method) {
case "get":
return 'get...';
case "post":
return 'post...';
default:
const _exhaustiveCheck: never = method; // 报错:不能将类型“string”分配给类型“never” ,因为 put 的情况没有列举
return _exhaustiveCheck;
}
}
类型别名和接口方便我们封装编写对象类型和联合类型,以便可以多次使用
// 联合类型
type ID = string|number
let id:ID = 1
id = '1'
// 对象类型
type Student = {
name:string;
age:number;
}
let LiHua:Student = {
name:'LiHua';
age:18;
}
// 函数类型
type Fun = (value:'string')=>number
const geString:Fun = (value)=>{
return value.length
}
interface Teacher {
name: string;
age: number;
say(msg: string): string;
}
const LiHe: Teacher = {
name: 'LiHe',
age: 25,
say(msg) {
return `老师格言:${msg}`
}
}
我们认为一个变量可能有两种或两种以上的类型时,即称为联合类型:
interface Student {
name: string;
study:()=>{};
}
interface Teacher {
name:string;
teach: () => {};
}
function handle(people:Student|Teacher) {
}
此时由于我们未知people形参的类型,所以不能直接给该形参设置方法调用:
function handle(people:Student|Teacher) {
people.study()
// 报错:类型“Student | Teacher”上不存在属性“study”。类型“Teacher”上不存在属性“study”。
}
所以此时我们就需要设置类型保护,类型保护主要有以下四种方法:
function handle(people: Student | Teacher, flag: 1 | 2) {
if (flag === 1) {
(people as Student).study()
} else {
(people as Teacher).teach()
}
}
function handle(people: Student | Teacher) {
if('study' in people) {
people.study()
} else {
people.teach()
}
}
function operation(x: number | string, y: number | string) {
if (typeof x === "string" || typeof y === "string") {
return `${x}${y}`;
}
return x + y;
}
class Student {
name: string;
study: () => {};
}
class Teacher {
name: string;
teach: () => {};
}
function handle(people: Student | Teacher) {
if(people instanceof Student) {
people.study()
} else {
people.teach()
}
}
const isString = (val: any): val is string => typeof val === 'string';
const isArray = (val: any):val is Array<any> => Array.isArray(val);
function fun(value: number | []) {
if(isArray(value)) {
return value.length
} else {
return value
}
}
泛型是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型,在未确定时泛型可以代表任意类型。
例如:
function handle<T>(x: T, y: T): T {
if (x === y) {
return x
} {
return y
}
}
handle<number>(1, 1)
handle<boolean>(true, false)
function handle<T>(arr: T[]): T {
return arr[0]
}
handle<number>([1,2,3])
function handle<T1, T2>(x: T1, y: T2) {
return `${x}.${y}`
}
handle<number,string>(1,'第一项内容')
当我们知道一个泛型类型一定具有一个 “length” 属性且想调用该属性时是无法直接调用的,我们需要对已定义的泛型进行约束,例如:
function handle<T>(value:T) {
return value.length
// 报错:类型“T”上不存在属性“length”。
}
我们需要修改为:
function handle<T extends { length: number }>(value: T) {
return value.length
}
handle<number[]>([1,2]) // 打印:2
<script setup lang="ts">
import { ref, reactive , computed } from 'vue'
import type { Ref } from 'vue'
// ref
// 可通过 Ref 或 调用ref时传入一个泛型参数
type code = number | string
let ts_ref1 = ref<string>('字符类型')
let ts_ref2: Ref<number[]> = ref([1, 2])
let ts_ref3 = ref<code>(1)
ts_ref3.value = '1'
// reactive
// 显性的给变量进行标注
interface student {
name: string,
age?: number,
[orders: string]: any
}
const ts_reactive:student = reactive({
id: 1,
name:'小明',
age:12,
})
// computed
// 调用computed时传入一个泛型参数
let data = ref<number>(1)
const ts_computed = computed<number>(()=>data.value*10)
</script>
<script setup lang="ts">
// 获取dom
const title = ref<HTMLElement|null>()
const handleClick = (event:Event): void=>{
console.log("event=>", event);
console.log("dom=>",title.value);
}
</script>
<template>
<div class="dataDefinition">
<div class="moduel">
<h3 ref="title">function-ts:事件标注和dom获取:h3>
<button @click="handleClick">打印event和标题dombutton>
div>
div>
template>
<script setup lang="ts">
import { ref} from "vue";
import student from "./components/student.vue";
let msg = ref<string>('父组件向子组件的通信数据...')
</script>
<template>
<div class="communication">
<div class="moduel">
<h3>子组件相关:h3>
<student :msg="msg">student>
div>
div>
template>
<script setup lang="ts">
const props = withDefaults(defineProps<{
msg: string,
id?:number|string // 非必传参数
}>(),{
// 设置默认值
msg:'暂无数据'
})
</script>
<template>
<div class="student">
{{ props.id }}、{{ props.msg }}
div>
template>
<template>
<div class="communication">
<div class="moduel">
<h3>子组件相关:h3>
<student @get-data="getdata">student>
div>
div>
template>
<script setup lang="ts">
const getdata = (value:string)=>{
console.log(value);
}
</script>
<template>
<button @click="getData">调用父亲getData方法,打印数据button>
template>
<script setup lang="ts">
const emits = defineEmits<{
(e:'getData',value:string):void
}>()
const getData = ()=>{
emits('getData','子组件向父组件的通信数据')
}
script>
如:
import type { Ref } from 'vue'
提示:文章到此结束,文章仅为个人学习记录,若有不足还请大家指出。