0

我想只循环某个类的某些键。我不想使用索引签名[key:string]:any,因为不推荐。

这是我的想法:

interface I {
    a: string,
    b: number
}

type NullKeysOf<T> = {
    [P in keyof T]: null
}

type PartialNullKeysOf<T> = Partial<NullKeysOf<T>>;

const obj:PartialNullKeysOf<I> = {
    a:null
}

class A<M extends I> implements I{
    a:string;
    b:number;
    obj:PartialNullKeysOf<M>
    constructor(a:string, b:number, obj:PartialNullKeysOf<M>){
        this.a = a;
        this.b = b;
        this.obj = obj;
    }
    public loop(){
        for(const k in this.obj){
            console.log(this[k]);
        }
    }
}

const a = new A<I>('',3,obj);

a.loop();

这是打字稿游乐场链接

我得到了错误

Type 'Extract<keyof M, string>' cannot be used to index type 'this'.

为什么k循环中的类型是Extract<keyof M, string>?不应该typeof I吗?

4

1 回答 1

0

为什么循环中k的类型是Extract<keyof M, string>?

您将 member 键入objPartialNullKeysOf<M>for...in循环枚举对象的string键,因此类型k被推断为“从类型 M 的给定值获取所有字符串键”:

  1. keyof MM为您提供(string | number | symbol联合)中的键类型
  2. Extract只留下类型的键string(第二个泛型类型参数)
  3. 泛型类类型参数是M,不是I(尽管受约束I

以上所有结果都k被推断为Extract<keyof M, string>

不应该是我的类型吗?

不,不应该,见第 3 点。extends泛型类型参数不是关于继承,而是类型的兼容性。M检查是否与 兼容I

类型 'Extract<keyof M, string>' 不能用于索引类型 'this'

正如评论中已经指出的那样, and 之间没有相关性IM您知道它们相同的事实并不意味着编译器可以安全地假设。幸运的是,在您的情况下,可以避免类型断言:

public loop(this: A<M> & M){ // <-- "this" now knows about members of M 
        for(const k in this.obj){
            console.log(this[k]); //OK
        }
    }

this参数确保您既保留this( ) 的原始类型,又明确告诉A<M>编译器具有 type 的成员。thisM

操场

于 2021-02-12T02:46:15.190 回答