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

TypeScript泛型keyof等概念困惑及ModelProperty类赋值报错疑问

Why does let valueWhyError: V = t[this.name]; throw an error in this TypeScript generic class?

Hey there! Let's unpack why that error is popping up in your ModelProperty class. It all comes down to how TypeScript handles generic parameters and type inference for class properties.

The Root Causes

  • V is an independent generic parameter (not strictly tied to T[P])
    Your class sets V = T[P] as a default type, but V remains a separate generic parameter. This means someone could explicitly pass a type for V that's narrower than T[P]. For example:

    // Here V is explicitly set to 22, not just the broader `number` type
    const engineProp = new ModelProperty<Car, 'engine', 22>('engine', 22);
    

    In this scenario, t[this.name] resolves to type number (since Car['engine'] is number), but you're trying to assign it to a variable of type 22—which TypeScript correctly rejects, because not all numbers are equal to 22.

  • TypeScript can't guarantee T[P] matches V in the method
    Even if you never explicitly override V, TypeScript's type system doesn't assume that V will always equal T[P] inside the fun method. Since V is a standalone generic parameter, it could be modified in a subclass or other instantiations where V diverges from T[P]. TypeScript prioritizes type safety here, so it throws an error instead of making an unsafe assumption.

Fixes to Resolve the Error

  • Remove the V generic parameter entirely
    If you don't need to narrow V beyond the type of T[P], just use T[P] directly for the value property. This eliminates the type mismatch entirely:

    export class ModelProperty<T, P extends keyof T> {
      constructor(public name: P, public value: T[P]) { }
      fun(t: T){
        let valueWhyFixed: T[P] = t[this.name]; // No error!
      }
    }
    
  • Add a constraint to tie V to T[P]
    If you do need to keep V (for cases where you want a more specific type), add a constraint V extends T[P] and use a type assertion if you're confident the assignment is safe:

    export class ModelProperty<T, P extends keyof T, V extends T[P]> {
      constructor(public name: P, public value: V) { }
      fun(t: T){
        let valueWhyFixed: V = t[this.name] as V; // Type assertion resolves the error
      }
    }
    

    Note: Type assertions bypass TypeScript's type checking, so only use this if you're certain t[this.name] will always be compatible with V in your specific use cases.

内容的提问来源于stack exchange,提问作者amitdigga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:38:19