javascript - Hvorfor et grensesnittargument tillater hvilken som helst type
Jeg prøver å arve grunngrensesnittet IScreen som skal utvides med IModal, IEmbedded eller ITab, og låse metoder slik at de er spesifikke for et grensesnitt. Men hva som skjer er at metoden public OpenModal(modal: IModal) av en eller annen grunn bare godtar hvilken som helst type.
Lekeplass
namespace Framework {
"use strict";
interface IScreen { }
interface IModal extends IScreen { }
interface ITab extends IScreen { }
interface IEmbedded extends IScreen { }
class BaseScreen implements IScreen {
public HandleCloseEvent() {
}
}
class DetailsScreen extends BaseScreen implements IModal {
}
class ListScreen extends BaseScreen implements IEmbedded {
}
class OpenerService {
public OpenScreen(screen: IScreen) {
}
public OpenModal(modal: IModal) {
}
}
class Controller {
constructor(openerService: OpenerService) {
var detailsScreen: DetailsScreen = new DetailsScreen();
var listScreen: ListScreen = new ListScreen();
openerService.OpenModal(212121); // Expected error
openerService.OpenModal(listScreen); // Expected error
}
}
}
- Mangler jeg noen kompilatorinnstillinger siden jeg ikke får noen feil?
- Misforstår jeg hvordan grensesnitt fungerer?
Svar #1
Det er slik TypeScript fungerer: med strukturell typethet (kalt også duck typing).
Du erklærer:
public OpenModal(modal: IModal) {
}
Fordi alle grensesnittene dine er tomme, er det ekvivalent med å skrive:
public OpenModal(modal: {}) {
}
Denne signaturen godtar alle objekter, fordi alle objekter er kompatible med et tomt objekt. 212121 er et objekt (i JavaScript er et tall et objekt). listScreen er også et objekt.
Du kan legge merke til at det er nytteløst å erklære flere grensesnitt for den tomme objekttypen:
interface IScreen { }
interface IModal extends IScreen { }
interface ITab extends IScreen { }
interface IEmbedded extends IScreen { }
Her er alle grensesnittene dine likeverdige. Det finnes ingen hierarki. Du kan gjøre:
let a: IScreen
let b: IModal
let c: IModal = a // type '{}' ('IScreen') is compatible to type '{}' ('IModal')
let d = {}
let e: IModal = d // type '{}' is compatible to type '{}' ('IModal')
Se også:
- Hva er strukturell typisering?
- Håndboken om grensesnitt
- Typer er strukturelle
