为什么 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 没有正确强制执行此限制。正在接受 N1 和其他不在数组中的类的实例。

问题:为什么 TypeScript 允许接受类型数组中未列出的类的实例?如何强制测试仅接受类型数组中特别列出的类的实例?

与类似问题的区别:

  • 我的问题特定于使用 InstanceType 根据预定义列表限制有效实例。

  • 我见过的类似问题通常讨论更广泛的类型兼容性或类实例类型检查,但没有解决基于类构造函数数组强制限制的特定用例。

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

您没有收到错误的原因是您的所有类都是空对象。空对象将与每个非空类型匹配。这是因为 Typescript 通过结构而不是名称来比较类型。例如,typescript 不会检查类型是否名为 T1,它会检查它是否具有 T1 所需的所有属性。如果 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;
}

游乐场链接

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