ts学习笔记

1. keyof ,类型索引的使用

keyof 类似于 Object.keys ,用于获取一个接口中 Key 的联合类型

interface Button {
    type: string
    text: string
}

type ButtonKeys = keyof Button
// 等效于
type ButtonKeys = "type" | "text"

type Kin = keyof any
//等效于
type Kin = string | number | symbol

2.extends,对泛型进行类型约束

type BaseType = string | number | boolean

// 这里表示 copy 的参数
// 只能是字符串、数字、布尔这几种基础类型
function copy<T extends BaseType>(arg: T): T {
  return arg
}

extends 经常与 keyof 一起使用,例如我们有一个方法专门用来获取对象的值,但是这个对象并不确定,我们就可以使用 extendskeyof 进行约束

function getValue<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}

const obj = { a: 1 }
const a = getValue(obj, 'a')

3. Partial, 将一个接口的所有属性变成可选的

type Partial<T> = {
    [P in keyof T]?: T[P]|undefin
}
interface Cat{
  nick:string
  color:string
}
const c1: Cat={
  nick:'tom',
  color:'grey'
}
const c2: Partial<Cat>={
  
}

4.Required,将一个接口的属性全部变成必选

type Required<T> = { [P in keyof T]-?: T[P]; }
interface Cat{
  nick?:string
  color?:string
}
const c1: Cat={
}
const c2: Required<Cat>={
  nick:'tom',
  color:'grey'
}

5.Recorde ,构造一个对象类型

它的属性键是K,属性值类型是T

type Record<K extends string | number | symbol, T> = { [P in K]: T; }

interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

6.Pick<Type, Keys>,提取接口的属性生成一个新的类型

type Pick<T, K extends keyof T> = {
    [P in K]: T[P]
}
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}
 
type TodoPreview = Pick<Todo, "title" | "completed">;
 
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

7.Extract<Type, Union> 构造一个Type和Union交集的新类型

type Extract<T, U> = T extends U ? T : never
type T0 = Extract<"a" | "b" | "c", "a" |"b" |"f">;
const t:T0 = 'a' //a或b

8.Exclude<UnionType, ExcludedMembers> 与Extract相反,排除交集,构造一个新类型

type Exclude<T, U> = T extends U ? never : T
type T0 = Exclude<"a" | "b" | "c", "a">;
     
// type T0 = "b" | "c"

9.Omit<Type, Keys>,与Pick相反,去除Types类型中的keys,构造一个新类型

type Omit<T, K extends string | number | symbol> = { 
  [P in Exclude<keyof T, K>]: T[P]; 
}
interface Todo {
  title: string;
  description: string;
  completed: boolean;
  createdAt: number;
}
 
type TodoPreview = Omit<Todo, "description">;
 
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  createdAt: 1615544252770,
};

10.ReturnType<Type>,构造一个函数返回值类型

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
type T0 = ReturnType<() => string>; //string
function f1 ():{a:number,b:string}{
  return {
    a:1,
    b:'2'
  }

}
type T4 = ReturnType<typeof f1>;
     
type T4 = {
    a: number;
    b: string;
}

11.InstanceType<Type>,构造由 Type 中构造函数的实例类型组成的类型。

type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any
class C {
  x = 0;
  y = 0;
}
 
type T0 = InstanceType<typeof C>;
const a:T0 = {
  x:1,
  y:2
}

<think>好的,我现在需要帮助用户找到在TypeScript中defineProps的类型定义。首先,用户提供的引用内容主要涉及Vue 3中使用defineProps的不同方式,特别是运行时声明和基于类型的声明。用户可能在使用TypeScript时遇到了如何正确定义props类型的问题,或者想了解defineProps在TypeScript中的类型定义结构。 根据引用[2]和[3],defineProps有两种用法:一种是传统的运行时声明,使用对象形式定义props的类型和验证规则;另一种是基于TypeScript的泛型,直接通过泛型参数指定props的类型。用户可能想了解这两种方式在TypeScript中的具体类型定义,以及如何正确使用它们。 引用[5]提到使用withDefaults来为props提供默认值,尤其是在使用基于类型的声明时。这可能意味着当使用泛型定义props时,默认值需要额外处理,而运行时声明则可以直接在对象中设置default属性。因此,用户可能想知道这两种方式在类型定义上的区别,以及如何结合TypeScript来确保类型安全。 接下来,我需要查看Vue 3的官方文档,特别是关于组合式API和TypeScript的部分。根据引用[4],Vue 3官网提到可以使用接口来定义props的类型,并通过泛型传递给defineProps。同时,引用[5]中的示例展示了如何为复杂类型定义props,并使用withDefaults来设置默认值。 综合这些信息,defineProps在TypeScript中的类型定义主要依赖于泛型参数。当使用基于类型的声明时,defineProps接受一个泛型参数,该参数是一个对象类型,定义了各个props的名称和类型。例如,defineProps<{ money: number, car?: string }>()。这种方式下,Vue会在编译时进行类型检查,而不是在运行时。 对于运行时声明,类型定义是通过PropType来指定更复杂的类型,如引用[1]中的例子,使用String as PropType<'on' | 'off'>来限制status的可能值。这种情况下,类型检查发生在运行时,但PropType允许结合TypeScript的类型系统来增强类型安全。 总结起来,用户可能需要了解两种方式的类型定义方法,以及如何选择适合自己项目的方式。需要指出的是,基于类型的声明(使用泛型)是Vue 3推荐的方式,因为它能更好地利用TypeScript的静态类型检查,减少运行时开销,并且代码更简洁。 最后,用户的问题可能涉及到如何在TypeScript项目中正确定义props的类型,确保类型安全和正确的默认值处理。因此,回答中需要明确两种方法的类型定义方式,并举例说明,同时引用官方文档和相关示例来支持说明。</think>在 Vue 3 的 TypeScript 项目中,`defineProps` 的类型定义分为两种模式,以下是具体说明: --- ### 一、基于类型的声明(推荐) 通过泛型参数直接定义 props 的**静态类型**,Vue 会在编译阶段进行类型检查,无需额外运行时验证。 **语法结构**: ```typescript const props = defineProps<{ 属性名: 类型 属性名?: 可选类型 // 可选参数 }>(); ``` **示例**: ```typescript // 直接定义类型 const props = defineProps<{ title: string count: number disabled?: boolean items: Array<{ id: number; value: string }> }>(); ``` **复杂类型处理**: 若需要定义接口或联合类型,可使用 `interface` 或 `type`: ```typescript interface Item { id: number label: string } defineProps<{ list: Item[] mode: 'edit' | 'preview' }>(); ``` **默认值设置**: 需配合 `withDefaults` 工具函数[^5]: ```typescript const props = withDefaults(defineProps<{ color?: string size?: number }>(), { color: 'red', size: 12 }); ``` --- ### 二、运行时声明(兼容传统写法) 使用 Vue 的 `PropType` 工具类型定义**运行时类型验证**,类型检查发生在代码执行阶段。 **语法结构**: ```typescript import { PropType } from 'vue' defineProps({ 属性名: { type: 具体类型 as PropType<TS类型>, required: true, default: 默认值 } }) ``` **示例**: ```typescript defineProps({ status: { type: String as PropType<'on' | 'off'>, // 限定特定字符串值 required: true }, metadata: { type: Object as PropType<{ id: number; data: string }>, default: () => ({ id: 0, data: '' }) } }); ``` --- ### 三、类型定义源码参考 在 Vue 类型声明文件(如 `vue.d.ts`)中,`defineProps` 的泛型定义如下: ```typescript declare function defineProps<PropsOptions = {}>(): PropsOptions; ``` 当传递泛型参数时,TypeScript 会将其映射为组件的 props 类型[^2][^4]。 --- ### 两种模式对比 | 特性 | 基于类型的声明 | 运行时声明 | |---------------------|--------------------------|--------------------------| | **类型检查阶段** | 编译时 | 运行时 | | **代码简洁度** | 更简洁 | 需显式类型转换 | | **默认值支持** | 需 `withDefaults` | 直接通过 `default` 属性 | | **复杂类型支持** | 原生 TS 类型 | 需配合 `PropType` | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值