仅循环打字稿中类的某些键

问题描述

我只想循环一个类的​​某些键。我不希望使用索引签名[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();

这是打字机游乐场link

我得到了错误

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

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

解决方法

为什么循环中k的类型是Extract

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

  1. keyof M 为您提供 M (string | number | symbol union) 中的键类型
  2. Extract 只留下 string 类型的键(第二个泛型类型参数)
  3. 通用类类型参数是 M,而不是 I(尽管 Iconstrained

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

不应该是我的类型吗?

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

类型 'Extract' 不能用于索引类型 'this'

正如评论中已经指出的,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 parameter 确保您既保留 this (A<M>) 的原始类型,并明确告诉编译器 this 具有类型的成员M

Playground

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...