首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Typescript + keyof。声明一个对象转换

TypeScript 中的 keyof 关键字用于获取某种类型的所有键的联合类型。当你想要创建一个函数,该函数接受一个对象和一个键,并返回该键对应的值时,keyof 就非常有用。

基础概念

keyof 是 TypeScript 的索引访问类型,它允许你从一个类型中提取键的类型。例如,如果你有一个对象类型 Person,你可以使用 keyof Person 来获取所有可能的键的类型。

类型声明示例

假设我们有一个 Person 接口:

代码语言:txt
复制
interface Person {
  name: string;
  age: number;
  email: string;
}

我们可以使用 keyof 来创建一个函数,该函数接受一个 Person 对象和一个键,并返回对应的值:

代码语言:txt
复制
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

在这个函数中,T 是任意类型,KT 的键的联合类型。函数返回的是 T[K],即 obj[key] 的类型。

应用场景

这种模式在处理通用函数时非常有用,尤其是在需要根据键来访问对象属性的情况下。例如,你可能有一个通用的数据获取函数,它可以用于任何对象:

代码语言:txt
复制
const person: Person = {
  name: 'Alice',
  age: 30,
  email: 'alice@example.com'
};

const name = getProperty(person, 'name'); // name 的类型是 string
const age = getProperty(person, 'age');   // age 的类型是 number

遇到的问题及解决方法

如果你在使用 keyof 时遇到问题,可能是因为 TypeScript 无法正确推断出键的类型。这通常发生在泛型参数没有被正确约束的情况下。确保你的泛型参数 TK 被正确地约束和使用。

例如,如果你尝试使用一个不存在的键,TypeScript 应该会给出错误提示:

代码语言:txt
复制
const invalid = getProperty(person, 'invalidKey'); // 错误:'invalidKey' 不在 'name' | 'age' | 'email' 中

如果你确实需要处理可能不存在的键,你可以使用可选链或者默认值来避免运行时错误:

代码语言:txt
复制
function getPropertyOrDefault<T, K extends keyof T>(obj: T, key: K, defaultValue: T[K]): T[K] {
  return obj[key] ?? defaultValue;
}

在这个改进的函数中,如果 obj[key]undefined,则会返回 defaultValue

总结

keyof 是 TypeScript 中一个强大的工具,它允许你创建灵活且类型安全的函数。通过正确使用泛型和索引访问类型,你可以编写出既通用又健壮的代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

TypeScript类型断言-类型的声明和转换

).substr(0,1)}func(1)我们可以看到编辑器中没有报错,如下:但是编译成JS后,运行过程中就报错了,如下:所以除非确切的知道变量的数据类型,否则不要使用类型断言,这是因为类型断言会让 TypeScript...(); }这里出一个面试题,如下:// 面试题 const a: number | undefined = undefined;const b: number = a!...以VScode编辑器为例点击设置按钮后,选择设置选项图片搜索strictNullChecks,然后勾选下面的选项就可以啦图片(2)肯定断言-肯定化保证赋值含义:允许在实例属性或者变量声明后面放置一个 !...我们可以在变量声明的时候就告诉编辑器该属性一定会被赋值,即在变量名后面加个!符号let score!

37910
  • 【TypeScript】TS类型断言-类型的声明和转换(七)

    val).substr(0,1)}func(1)我们可以看到编辑器中没有报错,如下: 但是编译成JS后,运行过程中就报错了,所以除非确切的知道变量的数据类型,否则不要使用类型断言,这是因为类型断言会让 TypeScript...(); }这里出一个面试题,如下:// 面试题 const a: number | undefined = undefined;const b: number = a!...以VScode编辑器为例点击设置按钮后,选择设置选项搜索strictNullChecks,然后勾选下面的选项就可以啦 (2)肯定断言-肯定化保证赋值含义:允许在实例属性或者变量声明后面放置一个 !...startClass();console.log('' + score); // 使用前赋值function startClass() { score = 5;}编辑器中会直接报错,我们可以在变量声明的时候就告诉编辑器该属性一定会被赋值

    57310

    让你的TypeScript代码更优雅,这10个特性你需要了解下

    六、掌握 TypeScript 的 keyof 类型操作符 TypeScript 的 keyof 操作符用于创建一个对象类型的所有键的联合类型,这一特性能帮助你创建依赖于其他类型键的动态和灵活的类型定义...通过 keyof 操作符,你可以更加灵活地操作对象类型,提升代码的可维护性和可扩展性。下面我们通过一个具体的例子来详细介绍 keyof 操作符的用法。...1、keyof 操作符的基本用法 keyof 操作符会提取一个对象类型的所有键,并将这些键组成一个联合类型。...3、动态对象属性 keyof 操作符在处理动态对象属性时特别有用。...十、巧用 TypeScript 声明合并提升代码灵活性 TypeScript 的声明合并(Declaration Merging)允许你将多个声明合并为一个实体。

    28310

    深入理解 TypeScript 中的 Keyof 运算符,让你的代码更安全、更灵活!

    三、 KeyOf 与映射类型的结合使用 在 TypeScript 中,我们可以使用 keyof 运算符与映射类型结合,将现有类型转换为新类型。...映射类型基于索引签名,通过迭代键来定义尚未声明的属性类型。...使用 KeyOf 运算符创建联合类型 在 TypeScript 中,当我们在具有显式键的对象类型上使用 keyof 运算符时,它会创建一个联合类型。...五、索引签名与 KeyOf 运算符 在 TypeScript 中,keyof 运算符可以与索引签名一起使用,以移除索引类型。索引签名用于表示对象的类型,其中对象的值是一致的类型。...通过使用 keyof stringMapDemo,我们确保传递的 property 是一个字符串类型的键。 六、使用 KeyOf 条件映射类型 条件类型用于根据条件表达式在两个声明的类型之间进行选择。

    24510

    分享 40 道关于 Typescript 的面试题及其答案

    答案:TypeScript 中的“keyof”关键字是一个类型运算符,它返回表示对象键的文字类型的联合。它允许您对对象键执行类型安全操作。...答案:条件类型中的“keyof”关键字用于获取对象类型的键的并集。它允许您以类型安全的方式使用对象的键。“in”关键字检查属性键是否存在于从“keyof”获得的键的并集中。...答案:TypeScript 条件类型中的“keyof T extends K”构造用于使用“extends”关键字根据指定条件过滤对象类型的键。...答案:TypeScript 中的模块扩充允许您在外部模块中添加新声明或扩展现有声明。当您想要向第三方库添加功能时,它非常有用。...答案:TypeScript 中的“keyof”运算符用于获取对象类型的键的并集。它允许您以类型安全的方式使用对象的键。

    90730

    速查手册 - TypeScript 高级类型 cheat sheet

    版本引入的,附中文 TypeScript 2.8 引入条件类型 lib.es2015.d.ts:大部分的声明在这个文件中可以找到 TypeScript 强大的类型别名:行文结构比较合理,也比较完善,可以当手册来查...X : Y 表示,如果 T 可以赋值给 U (类型兼容),则返回 X,否则返回 Y; 1.3、使用 `keyof` 和 `in` keyof 可以用来取得一个对象接口的所有 key 值: interface...TypeScript 为此提供了一个示例,他们创建了一个叫作 Flatten 的类型,用于将数组转成他们需要的元素类型: type Flatten = T extends any[] ?...R : any; 解释: 我们可以用 infer 声明一个类型变量,是用它获取函数的返回类型,简单说就是用它取到函数返回值的类型方便之后使用....源码: // node_modules/typescript/lib/lib.es5.d.ts interface ThisType { } 解释: 可以看到声明中只有一个接口,没有任何的实现

    1.3K10

    【TypeScript 演化史 — 第七章】映射类型和更好的字面量类型推断

    TypeScript 2.1 引入了映射类型,这是对类型系统的一个强大的补充。本质上,映射类型允许w咱们通过映射属性类型从现有类型创建新类型。根据咱们指定的规则转换现有类型的每个属性。...转换后的属性组成新的类型。 使用映射类型,可以捕获类型系统中类似 Object.freeze() 等方法的效果。冻结对象后,就不能再添加、更改或删除其中的属性。...对于希望在应用程序中冻结的每种类型的对象,咱们就必须定义一个包装器函数,该函数接受该类型的对象并返回冻结类型的对象。没有映射类型,咱们就不能以通用的方式静态地使用 Object.freeze()。...[P in keyof T]: T[P]表示将 T类型的每个属性 P 的类型转换为 T[P]。如果没有readonly修饰符,这将是一个身份转换。...该方法返回一个新对象,该对象只包含咱们选择的属性。可以使用Pick对该行为进行构建,正如其名称所示。

    3.8K40

    【TypeScript 演化史 -- 7】映射类型和更好的字面量类型推断

    TypeScript 2.1 引入了映射类型,这是对类型系统的一个强大的补充。本质上,映射类型允许w咱们通过映射属性类型从现有类型创建新类型。根据咱们指定的规则转换现有类型的每个属性。...转换后的属性组成新的类型。 使用映射类型,可以捕获类型系统中类似 Object.freeze() 等方法的效果。冻结对象后,就不能再添加、更改或删除其中的属性。...对于希望在应用程序中冻结的每种类型的对象,咱们就必须定义一个包装器函数,该函数接受该类型的对象并返回冻结类型的对象。没有映射类型,咱们就不能以通用的方式静态地使用 Object.freeze()。...[P in keyof T]: T[P]表示将 T类型的每个属性 P 的类型转换为 T[P]。如果没有readonly修饰符,这将是一个身份转换。...该方法返回一个新对象,该对象只包含咱们选择的属性。可以使用 Pick 对该行为进行构建,正如其名称所示。

    2.9K10

    《现代Typescript高级教程》高级类型

    ,它允许我们在编译时转换已知类型的属性,并创建一个新的类型。...Record Record 是一个映射类型,它根据指定的键类型和值类型创建一个新的对象类型。...当T是一个函数类型时,我们使用infer R声明一个类型变量R来推断函数的返回类型,并将其作为结果返回。...infer关键字的作用是告诉 TypeScript 编译器在条件类型中推断一个待定的类型,并将其赋值给声明的类型变量。这使得我们可以在条件类型中使用这个推断出的类型进行进一步的类型操作。...infer关键字是 TypeScript 中用于提取并推断待定类型的工具。它允许我们在条件类型中声明一个类型变量,用于在类型推断过程中捕获和使用待推断的类型,从而使类型系统更加灵活和强大。

    21730

    TS 从 0 到 1 - 泛型

    K(Key):表示对象中的键类型 V(Value):表示对象中的值类型 E(Element):表示元素类型 不只能定义一个类型变量,可以引入希望定义的任何数量的类型变量。...myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; }; # 泛型工具类型 # typeof typeof 用来获取一个变量声明或对象的类型...}; // string | number 在 TypeScript 中支持两种索引签名,数字索引和字符串索引: interface StringArray { [index: string]...原因是当使用数值索引时,JavaScript 在执行索引操作时,会先把数值索引先转换为字符串索引。...c"; type Obj = { [p in Keys]: any; }; // { a: any, b: any, c: any } # infer 在条件类型语句中,可以用 infer 声明一个类型变量并进行使用

    40610

    TypeScript 类型系统中一个巧妙的设计

    为啥 TypeScript 不解决这种问题? 一般我们可以通过将 Object.keys(options) 强制转换为 (keyof typeof options)[] 来规避这种问题。...我们可以稍微做一下变更,让它接收一个泛型参数 T ,并且返回 (keyof T)[]: class Object { keys(o: T): (keyof T)[...TypeScript 中的结构类型 当一个对象的属性丢失或类型错误时,TypeScript 会抛出错误。...这里面的关键点就是:当我们拥有一个 T 类型的对象时,我们所知道的关于这个对象的一切就是它至少包含 T 中的所有属性。...利用结构类型 结构类型给我们提供了很大的灵活性,它允许接口准确地声明它们需要的属性。 下面我们再来举一个例子。 假如我们编写了一个函数,来解析键盘事件并返回要触发的快捷方式。

    26330

    TypeScript - keyof

    在 TypeScript 中,keyof 关键字是一个有用的类型操作符,它用于获取一个类型所有公共属性键的联合(Union)。当你想要操作一个类型的键而不是它的值时,keyof 操作符非常有用。...keyof Person 将包含所有这些可能的键以及明确声明的属性键 "age"。 类型守卫和断言 keyof 可以用来创建类型守卫,确保某个键存在于对象中。...,它只包含 Person 接口中那些被声明为必需的键。...person, 'name'); // string const age = getProperty(person, 'age'); // number 在这个例子中,getProperty 函数接受一个对象和一个键...泛型 K 被约束为 T 的键之一,这样 TypeScript 就可以确保键是有效的。 keyof 是 TypeScript 提供的一个强大的工具,它允许你以类型安全的方式操作对象的键。

    14910

    TypeScript进阶(三)类型演算与高级内置类型

    例如,typeof 操作符可以用于获取一个值的类型;keyof 关键字可以用于获取一个对象所有属性名组成的联合类型;in 关键字可以用于遍历一个联合类型中所有成员等等。...在 TypeScript 中,typeof 操作符也可以用于获取一个值的类型,并将其作为一个类型注解或类型声明使用。...keyof 关键字keyof 是 TypeScript 中的一个关键字,用于获取一个对象所有属性名组成的联合类型。...通过 keyof 关键字,我们可以在编译时获取对象属性名,并将其作为一个类型注解或类型声明使用。...in 关键字in 是 TypeScript 中的一个关键字,用于遍历一个联合类型中所有成员。通过 in 关键字,我们可以在编译时对联合类型进行遍历,并将其作为一个类型注解或类型声明使用。

    30810

    TypeScript中的高级类型工具类型及关键字

    本文主要帮助理解 TypeScript 中的高级类型及工具类型。在实际使用 TypeScript 的开发过程中,得益于这些高级类型于工具类型,我们可以更方便的构建出我们需要的类型。...它通常配合一组尖括号进行声明使用: // 一个带有 name 属性的类型 type Cup = { name: string; }; // 声明一个接收三个参数的函数, // 第一个参数是必须拥有name...属性的 object // 第二个参数设置为第一个参数这个对象中的一个属性 // 第三个参数设置为第二个参数的属性值 const addAttr = 一个类型即可 // 声明Foo类型 type Foo = { width: number; } // 声明一个Bar类型 type Bar = { height:...// 声明Foo类型 type Foo = { width: number } // 声明一个Bar类型 type Bar = { height: number } // 声明一个Foo, Bar的交叉类型

    2.1K30

    深入学习下 TypeScript 中的泛型

    事实上,一个几乎总是可以替代另一个。 主要区别在于接口可能对同一个接口有多个声明,TypeScript 将合并这些声明,而类型只能声明一次。...T> 为函数声明了两个参数类型,其中 K 被分配一个类型,该类型是 T 中的key的并集。...假设您有一个存储限制,您只能存储所有属性都具有字符串值的对象。为此,您可以创建一个函数,它接受任何对象并返回另一个对象,该对象具有与原始对象相同的键,但所有值都转换为字符串。...{} as { [K in keyof T]: string } 代码通过对空对象 {} 进行类型转换,将累加器初始值的类型设置为 { [K in keyof T]: string }。...,因此将此代码编译到您的 TypeScript 环境中会重新声明 Readonly 并引发错误。

    39K30

    深入学习下 TypeScript 中的泛型

    事实上,一个几乎总是可以替代另一个。主要区别在于接口可能对同一个接口有多个声明,TypeScript 将合并这些声明,而类型只能声明一次。...T> 为函数声明了两个参数类型,其中 K 被分配一个类型,该类型是 T 中的key的并集。...假设您有一个存储限制,您只能存储所有属性都具有字符串值的对象。为此,您可以创建一个函数,它接受任何对象并返回另一个对象,该对象具有与原始对象相同的键,但所有值都转换为字符串。...{} as { [K in keyof T]: string } 代码通过对空对象 {} 进行类型转换,将累加器初始值的类型设置为 { [K in keyof T]: string }。...TypeScript 中,因此将此代码编译到您的 TypeScript 环境中会重新声明 Readonly 并引发错误。

    17910

    【TypeScript 演化史 -- 6】对象扩展运算符和 rest 运算符及 keyof 和查找类型

    如果一个属性同时出现在两个对象中,则后分配的会替换前面的。 当然,TypeScript 理解这种顺序。...对象扩展仅拷贝属性值,如果一个值是对另一个对象的引用,则可能导致意外的行为。 keyof 和查找类型 JS 是一种高度动态的语言。在静态类型系统中捕获某些操作的语义有时会很棘手。...一个对象的不同属性可以有完全不同的类型,咱们甚至不知道 obj 是什么样子的。 那么如何在 TypeScript 中编写这个函数呢?...keyof 操作符号 在 JS 中属性名称作为参数的 API 是相当普遍的,但是到目前为止还没有表达在那些 API 中出现的类型关系。 TypeScript 2.1 新增加 keyof 操作符。...另一个真实的示例,请查看与TypeScript编译器一起发布的 lib.es2017.object.d.ts 类型声明文件中Object.entries()方法: interface ObjectConstructor

    2.6K30

    TypeScript系列教程九《类型转换》-- 映射类型

    类型转换是TS最好玩也是语言的灵魂,想玩好需要熟练各种手段和工具,下面一一介绍类型转换的一些常用手段。...Mapped Types ---- 有时候对象属性类型重复或者一个类型基于另一个了类型的时候 映射类型基于索引签名的语法构建,用于声明尚未提前声明的属性类型: type OnlyBoolsAndHorses...//type User = { //id: string; //name: string; //age: number; //} key 通过as 重新映射 在TypeScript...//type KindlessCircle = { //radius: number; //} 进一步探索 映射类型与此类型操作部分中的其他功能配合得很好,例如,这里有一个使用条件类型的映射类型...,该类型根据对象的属性pii是否设置为文本true返回true或false: type ExtractPII = { [Property in keyof Type]: Type[Property

    1.3K10
    领券