我试图确保函数只接受数组中定义的特定类的实例。这是我的 TypeScript 代码:
class Types { }
class T1 extends Types { }
class T2 extends Types { }
class T3 extends Types { }
class T4 extends Types { }
class T5 extends Types { }
class N1 extends Types { }
class NN { }
const types = [T1, T2, T3, T4, T5]
function test(type: InstanceType<typeof types[number]>) { }
test(T1) // ERROR: T1 is a class, not an instance.
test(T2) // ERROR: T2 is a class, not an instance.
test(N1) // ERROR: N1 is a class, not an instance.
test(NN) // ERROR: NN is a class, not an instance.
test(new NN()) // ERROR: Instance of NN, which is not in the types array.
test(new N1()) // ERROR: Instance of N1, which is not in the types array.
test(new T1()) // OK: Instance of T1, which is in the types array.
功能测试应该只接受类 T1、T2、T3、T4、T5 的实例。然而,没有任何应该产生错误的行会这样做。我希望 TypeScript 将接受的实例限制为仅从类型数组中列出的类创建的实例。
为什么这些行没有产生错误,以及如何正确执行此限制?
您没有收到错误的原因是您的所有类都是空对象。空对象将与每个非空类型匹配。回想一下,打字稿通过类型的形状而不是名称来比较类型。例如,它不会检查类型是否名为 T1,而是检查它是否具有 T1 所需的所有属性。
添加一个属性,您将开始收到预期的错误。
class Types {
a!: string;
}
class T1 extends Types {
b!: string;
}
class T2 extends Types {
c!: number;
}
class T3 extends Types {
d!: boolean;
}
class T4 extends Types {
e!: boolean;
}
class T5 extends Types {
f!: null
}
class N1 extends Types {
g!: { hello: 'world' }
}
class NN {
baz!: () => void;
}
请注意,即使进行了这些更改,
test(new N1())
也不会抛出错误。那是因为 N1 兼容
游乐场链接