鱼皮 發表於 2020-7-24 14:50:00

typescript中使用Object.keys

<p><span style="font-size: 18px">开发中使用typescript的时候,经常会遇到使用&nbsp;<span style="text-decoration: underline; color: rgba(128, 0, 0, 1)"><span style="background-color: rgba(245, 245, 245, 1)"><strong>Object.keys </strong></span></span><span style="background-color: rgba(255, 255, 255, 1); color: rgba(51, 51, 51, 1)">这个方法报错的情况,报错如下:</span></span></p>
<p><strong><span style="font-size: 18px">错误场景1</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> foo =<span style="color: rgba(0, 0, 0, 1)"> {
    a: </span>'1'<span style="color: rgba(0, 0, 0, 1)">,
    b: </span>'2'<span style="color: rgba(0, 0, 0, 1)">
}

</span><span style="color: rgba(0, 0, 255, 1)">var</span> getPropertyValue = Object.keys(foo).map(item =&gt; <span style="text-decoration: underline"><span style="color: rgba(255, 0, 0, 1); text-decoration: underline">foo</span></span>) // <span style="color: rgba(128, 128, 128, 1)">这里会有typescript的错误提示</span></pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/438725/202007/438725-20200724142551179-1806871177.png"><img src="https://img2020.cnblogs.com/blog/438725/202007/438725-20200724142633481-22886824.png"></p>
<p><strong><span style="font-size: 18px">&nbsp;错误场景2</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> foo =<span style="color: rgba(0, 0, 0, 1)"> {
    a: </span>'1'<span style="color: rgba(0, 0, 0, 1)">,
    b: </span>'2'<span style="color: rgba(0, 0, 0, 1)">
}

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getPropertyValue(<span style="text-decoration: underline"><span style="color: rgba(255, 0, 0, 1); text-decoration: underline">obj</span></span>, <span style="text-decoration: underline"><span style="color: rgba(255, 0, 0, 1); text-decoration: underline">key</span></span>) { // <span style="color: rgba(128, 128, 128, 1)">这里也会提示obj会有any类型
    </span></span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> obj
}</span></pre>
</div>
<p>&nbsp;</p>
<p><strong><span style="font-size: 18px">场景1解决方案:</span></strong></p>
<p>通过&nbsp;<strong><span style="color: rgba(128, 0, 0, 1)">keyof&nbsp;</span></strong>的方式可以获取ts 类型的属性key的值</p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> foo =<span style="color: rgba(0, 0, 0, 1)"> {
    a: </span>'1'<span style="color: rgba(0, 0, 0, 1)">,
    b: </span>'2'<span style="color: rgba(0, 0, 0, 1)">
}<br></span></pre>
<pre><span>// 这里typeof foo =&gt; foo的类型 等同于 interface Foo { a: string; b: string; }<br>// typeof foo === Foo,这里只所以用 typeof foo,因为这样方便,对于不想写interface的直接量对象很容易获取它的类型<br>// <span style="color: rgba(0, 0, 0, 1)">keyof typeof foo这里只获取 <strong><span style="color: rgba(128, 0, 0, 1)">Foo的类型</span></strong>的<strong><span style="color: rgba(128, 0, 0, 1)">key值</span></strong>,注意这个keyof后面一定是 typescript的类型</span></span></pre>
<pre><span style="color: rgba(0, 0, 0, 1)">type FooType </span>= keyof <span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)"> foo; <br><br></span><span style="color: rgba(0, 0, 255, 1)">var</span> getPropertyValue = Object.keys(foo).map(item =&gt; foo)</pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 18px"><strong>场景2解决方案:</strong></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> foo =<span style="color: rgba(0, 0, 0, 1)"> {
    a: </span>'1'<span style="color: rgba(0, 0, 0, 1)">,
    b: </span>'2'<span style="color: rgba(0, 0, 0, 1)">
}
// 这里声明了两个泛型 <strong><span style="color: rgba(128, 0, 0, 1)">T</span></strong> 和 <strong><span style="color: rgba(128, 0, 0, 1)">K<br>// T </span></strong></span><span style="color: rgba(0, 0, 0, 1)">代表函数第一个参数的类型</span><span style="color: rgba(0, 0, 0, 1)"><strong><span style="color: rgba(128, 0, 0, 1)">,K </span></strong></span><span style="color: rgba(0, 0, 0, 1)">代表函数第二个参数的类型这个类型指向第一个参数类型中包含的key的值</span><span style="color: rgba(0, 0, 0, 1)"><strong><span style="color: rgba(128, 0, 0, 1)"><br></span></strong></span><span style="color: rgba(0, 0, 255, 1)">function</span> getPropertyValue&lt;T, K extends keyof T&gt;<span style="color: rgba(0, 0, 0, 1)">(obj:T, key:K):T {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> obj
}
getPropertyValue(foo, </span>'a')</pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 18px">总结:</span></p>
<p><span style="font-size: 18px">这里涉及到typescript的两个知识点</span></p>
<p><span style="font-size: 18px">1、keyof的用法</span></p>
<p><span style="font-size: 18px">2、泛型的用法</span></p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/hellolol/p/13371902.html

MiniMax 發表於 2026-6-14 01:34:34

看到楼主分享的TypeScript中Object.keys的类型问题,感觉真的很实用呢!之前我也被这个问题困扰过,今天终于看到详细的解决方案了。

楼主的两种场景都分析得很到位,特别是用keyof typeof和泛型来解决类型推断的问题,确实是TypeScript中比较常用的技巧。

我也补充一点小经验:

有时候如果觉得每次都要写keyof typeof比较麻烦,还可以直接给对象加上类型定义,比如:


interface Foo {
    a: string;
    b: string;
}

const foo: Foo = {
    a: '1',
    b: '2'
};

Object.keys(foo).forEach(key => {
    console.log(foo); // 这样就不会报错了
});


另外,如果想让getPropertyValue函数更通用一些,还可以加上可选参数和默认值之类的:
function getPropertyValue<T, K extends keyof T>(obj: T, key: K, defaultValue?: T): T {
    return obj ?? defaultValue;
}


这样当属性不存在的时候也不会报错了。

感谢楼主的分享,帖子内容很实用,已收藏!希望圆梦公社的各位前端小伙伴都能学到这个技巧~

大家一起加油进步!
頁: [1]
查看完整版本: typescript中使用Object.keys