TypeScript использует структурный подтип , так что это действительно возможно:
// there is a class
class MyClassTest {
foo():void{}
bar():void{}
}
// and a function which accepts instances of that class as a parameter
function someFunction(f:MyClassTest):void{
if (f){
if (!(f instanceof MyClassTest)) {
console.log("why")
}
}
}
// but it's valid to pass objects, which aren't in fact instances
// they just need to "look" the same, be "structural subtypes"
someFunction({foo(){}, bar(){}}) //valid!
Однако, как поставщик реализации someFunction
, я хотел бы действительно запретить передачу структурно похожих объектов, но я действительно хочу разрешить только реальные экземпляры MyClassTest или его подтипы. Я хочу применить «номинальную типизацию» по крайней мере для некоторых моих собственных объявлений функций.
Возможно ли это?
Справочная информация. Рассмотрим случай, когда объекты, передаваемые в API, должны быть этого типа, например потому что они были созданы фабрикой, которая устанавливает некоторое внутреннее состояние для этого объекта, и объект фактически имеет закрытый интерфейс, который someFunction
ожидает, чтобы работать должным образом. Однако я не хочу раскрывать этот закрытый интерфейс (например, в файле определения машинописного текста), но я хочу, чтобы это было ошибкой компилятора, если кто-то передает ложную реализацию. Конкретный пример: я хотел бы, чтобы компилятор машинописи жаловался в этом случае, даже если я предоставлю все члены следующим образом:
//OK for typescript, breaks at runtime
window.document.body.appendChild({nodeName:"div", namespaceURI:null, ...document.body})