为什么 TypeScript 对于未包含在数组类型中的类实例不给出错误?

问题描述 投票:0回答:1

我试图确保函数只接受数组中定义的特定类的实例。这是我的 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 将接受的实例限制为仅从类型数组中列出的类创建的实例。

为什么这些行没有产生错误,以及如何正确执行此限制?

typescript typescript-generics instanceof type-safety
1个回答
0
投票

您没有收到错误的原因是您的所有类都是空对象。空对象将与每个非空类型匹配。回想一下,打字稿通过类型的形状而不是名称来比较类型。例如,它不会检查类型是否名为 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 兼容 游乐场链接

© www.soinside.com 2019 - 2024. All rights reserved.