You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript返回函数时类型无法推断问题咨询

Great question! The issue here boils down to how TypeScript infers generic types when dealing with curried functions. Let's break this down step by step.

Why propEq2 has inference issues

Your original propEq works because all three parameters (key, equals, object) are provided in a single call. TypeScript can look at the object parameter to infer T, then automatically narrow K to be a key of that T.

But propEq2 is curried: you first pass key and equals, then later pass object. When you call the first part (propEq2('key', value)), TypeScript has no way to infer T yet—because T is only used in the returned function's parameter. Since T is unknown at this point, K extends keyof T resolves to never (because keyof unknown is never), hence the type error.

Fixing the type inference for curried propEq2

We need to adjust the generic parameters to let TypeScript infer types incrementally as each part of the curried function is called. Here's the corrected version:

export const propEq2 = <K extends PropertyKey, V>(key: K, equals: V) => 
  <T extends Record<K, V>>(object: T) => object[key] === equals;

How this works:

  1. First call (propEq2('name', 'Alice')):
    • TypeScript infers K as the literal type of key (e.g., "name").
    • It infers V as the type of equals (e.g., string).
  2. Returned function:
    • Now we constrain T to be an object that has the key K with type V. When you pass the object later, TypeScript will check that it matches this constraint.

Usage example

// Works perfectly—TypeScript infers the returned function expects { name: string }
const isNameAlice = propEq2('name', 'Alice');
console.log(isNameAlice({ name: 'Alice', age: 30 })); // true
console.log(isNameAlice({ name: 'Bob' })); // false

// Type error (as expected!) because the object's 'age' is a string, not number
const isAge25 = propEq2('age', 25);
isAge25({ age: '25' }); // Error: Type 'string' is not assignable to type 'number'

Alternative approach (more granular currying)

If you prefer splitting the currying into smaller steps, this version also works great:

export const propEq2 = <K extends PropertyKey>(key: K) => 
  <V>(equals: V) => 
  <T extends Record<K, V>>(object: T) => object[key] === equals;

Here, you call it like propEq2('name')('Alice')({ name: 'Alice' }), and TypeScript infers types at each step without issues.

Content of the question originates from Stack Exchange, question author OliverRadini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:03:13