// ts声明简单类型
let number: number = 4
let str: string = '4'
let bool: boolean = true
let u: undefined = undefined
// 报错 不能将u赋值为string类型
// u = 's'
// undefined和null是所有类型的子类型
str = undefined
let n: null = null
// 报错 不能将n赋值为string类型
// n = '4'
// undefined和null是所有类型的子类型
u = n
let any: any = '4'
any = true
any = '4'
any = 3
any = undefined
any = null
// ts声明复杂类型---------》数组
let arr: any[] = [1,2,3,'4'] // 任意数组
let arr1: number[] = [1,2,3,] // 纯数字类型的数组
let arr2: string[] = ['1', '2'] // 纯字符串类型的数组
// ts 声明复杂类型---------》元组
let arr3: [string, number] = ['1', 5]
// 报错 不能将类型“[string, number, number]”分配给类型“[string, number]”。 源具有 3 个元素,但目标仅允许 2 个
// let arr4: [string, number] = ['1', 5, 5]
// 在使用数组的一些方法时,如push只能push已声明的类型 否则报错
arr3.push('456')
arr3.unshift(5)
// ts声明复杂类型--------》接口 interface
interface Person {
name: string,
age: number,
sex: string,
}
// user里面的属性必须和Person里面声明的属性保持一致(多少都不行),否则报错
let user : Person = {
name: '蔡徐坤',
age: 30,
sex: '女'
}
// 在接口中定义可选参数
interface Person1 {
name: string, // name 为必选参数
age?: number, // age? 为可选参数
sex?: string,// sex? 为可选参数
}
let user1 : Person1 = {
name: '蔡徐坤', // 如果不传则报错
}
// 在接口中定义只读属性
interface Person2 {
name: string
readonly id: number
}
let user2: Person2 = {
name: '蔡徐坤',
id: 2
}
// user2.id = 5 报错
// 泛型(类似占位符<>)
// 定义函数、接口和类的时候,先不设定类型,等到使用的时候才定义类型
function echo<T>(arg: T) :T {
return arg
}
const res = echo(123)
function swap<T, U>(arr:[T,U]):[U, T]{
return [arr[1], arr[0]]
}
const result = swap([123, 'str'])
const changeVal = <T>(val: T) => {}
changeVal<number>(9)
const changeVal: <T>(val: T) => T = (val) => {
console.log(val)
return val
}
changeVal<number>(9)
function changeV<T>(val: T) {}
changeV<string>('9')
function changeV<T>(val: T):T {
return val
}
changeV<string>('9')
// 泛型的约束
// 目的:只想返回一个具有length属性的函数
// function getLength<T>(length: T): T {
// 报错,因为不一定变量length中有length属性,此时使用泛型约束
// return length.length
// }
interface length {
length: number
}
function getLength<T extends length>(length: T): T {
return length
}
getLength('123')
getLength([1,2,3])
getLength({length: 50, name: '12313'})
// 在类中使用泛型
class Queue<T> {
private data = []
push(item: T) {
return this.data.push(item)
}
pop():T {
return this.data.shift()
}
}
const queue = new Queue<number>()
queue.push(1)
// 报错,不能push字符串
// queue.push('123')
// 编译时会报错,因为数字没有toFixed方法,此时ts检测不出来
console.log(queue.pop().toFixed());
interface keyPair<T, U> {
key: T,
value: U
}
const key:keyPair<number, string> = {key:1, value: '123'}
const key2:keyPair<string, number> = {key:'4564', value: 123}
// 两种写法等价
const arr_: number[] = [123, 456,]
const arr__: Array<number> = [123, 456]
// 字面量 只能是原始类型,赋值其他会报错
const strName: 'name' = 'name'
// 类型别名 type
type P = 'left' | 'right' | 'top' | 'down'
const position9: P = "right"
// 联合类型 |
const or = 'left' | 'right' | 'top' | 'down'
// 交叉类型 &
interface Inum {
num: number
}
type InumAndString = Inum & {name: string}
const nameLiu: InumAndString = {name:'xxx',num:4}
// ts函数(参数类型和返回值类型)如果不返回默认是void
function fn(x: number, y: number):number {
return x + y
}
fn(4, 5)
// 传递为对象,对象里面的参数限制
function count (a:{a:number,b:number}){
console.log(a);
}
count({a:2,b:5})
// 下面两种写法等价(接口定义函数和函数类型)
interface Ifn {
(x:number, y:number): number
}
const fn1:Ifn = function fn(x: number, y: number):number {
return x + y
}
const myFn :(x:number, y:number) => number = function (x:number, y:number):number {
return x + y
}
// 类型推断(上面的fn函数,如果fn函数返回值省略,ts会根据类型推断出fn返回的是number类型)
// enum 枚举类型 默认是0开始,也可以自定义,枚举的每一个值都是唯一的。
enum Color {
red,
green,
blue
}
const color = Color.red // color值为1
// 数字枚举
enum Color1 {
red = 10,
green = 20,
blue = 30
}
const color1 = Color1.red // color值为10
// 枚举支持反推,当我们明确枚举某个值时,能反推出key值(例:)
const colorKey = Color1[20] // colorKey为green
// 字符串枚举 如果字符串枚举对值进行初始化,则必须每个都要初始化,不然ts会报错
enum Directions {
UP = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
// 总结
// interface 定义接口,(object类型)
// enum 定义枚举类型
// type 定义类型别名
// as 类型断言
function getLengthFn (value: number | string) :number{
const str = value as string
if (typeof str === 'string') {
return str.length
} else {
const num = value as number
return num.toString.length
}
}
// 或直接用typeof检测类型
function getLengthFn1 (value: number | string) :number{
if (typeof str === 'string') {
return str.length
} else {
return value.toString.length
}
}
// 如何检查getProperty(x, "m")的报错(核心keyof:keyof该操作符可以用于获取某种类型的所有键,其返回类型是联合类型 )
function getProperty(obj, key :keyof IGetProperty):string {
return obj[key].toString();
}
interface IGetProperty {
a:number,
b:number,
c:number,
d:number
}
let x:IGetProperty = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a");
getProperty(x, "m");
//或者
function getProperty<T extends object, U extends keyof T>(obj: T, key :U):string {
return obj[key].toString();
}
const x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a");
getProperty(x, "m");
// 定义一个空对象,且对空对象后期赋值的对象约束
import { ref } from 'vue';
interface MyObject {
name: string;
age: number;
}
// 使用 Partial 让属性可选
const myObject = ref<Partial<MyObject>>({});
// 后续赋值时可以选择性地赋值
myObject.value = { name: "xxx" }; // 正确
myObject.value = { age: 1 }; // 正确