#Confusion with imported module name passed to an interface type parameter

17 messages · Page 1 of 1 (latest)

summer valley
#

I'm only asking how the hell does this work. I'm porting from some legacy code. There is too much code to include it all here so I have tried to include only enough to be explanatory.

I am trying to recreate a component declared as below:

import * as Translations from "../dictionary.i18n";
...
@Component({
    selector: "settingsgeneral",
    templateUrl: './SettingsGeneral.template.html'
})
export class SettingsGeneralComponent extends SettingsGeneral {
...
    constructor(settingsService: SettingsProvider, analyticsProvider: AnalyticsProvider) {
        super(settingsService, Translations, analyticsProvider);
    }

where ../dictionary.i18n.ts is a generated file that exports a whole lot of string constants for label texts.
The component derives from this class:

export class SettingsGeneral {
...
    constructor(
        private settingsService: ISettingsService,
        private translations: GeneralTranslations,
        private analyticsService: IAnalyticsService) {
    }

And GeneralTranslations is an interface with a few string fields:

export interface GeneralTranslations {
    ItemsPerPage:string;
    FontSizeValues:string;
    SettingsGeneralJurisdictionSortFilter:string;
}

How can the component template access fields on the translations property that aren't declared in GeneralTranslations? Notice how in the component ctor the imported module name, Translations (with upper-case T) is used as an argument for the call to the base class's ctor but in the base class that parameter is declared to be of type GeneralTranslations.

I'm guessing here that the type of the object actually passed to the base class ctor via the transactions parameter, being a set of constants, replaces the type GeneralTranslations. In the template I have, e.g. {{translations.StartPage}} but StartPage is not available on the GeneralTransactions interface yet it is available in the set of constants imported with from dictionary.i18n

#

I'm coming into Angular from a C# background so maybe I'm just used to a lot more type safety

queen willow
#

Since translations is private, you shouldn't even be able to access it from the template. Unless you're using an old version of Angular, in jit mode? Which version are you using?

summer valley
#

I actually have another question just about accessing a private translations from the template

#

I looked up an error message and found out protected fields were accessible so I thought maybe private as well

queen willow
summer valley
#

I'm getting so many build errors from some recently merged code I couldn't really get to a point to build just my changes, but thanks, I'll amend my variables to public

queen willow
summer valley
#

Hence my first question. I am porting some old code where it appears to access members that aren't part of the interface, but I can't get that old code running to check.

#

I've just avoided the interface in my new code and basically imported the constants file straight into my translations variable

queen willow
#

Your question was : "how the hell does this work". But it doesn't.

summer valley
#

I was assuming the old code worked and thinking maybe dynamic typing like in good old JS allowed this to happen. Thanks a lot for your time

queen willow
#

Hence my confusion and why I asked you which version of Angular you were using. That can't work with modern Angular. If it used to work, it was in a very old version, in JIT mode (i.e. no compilation of the templates to TypeScript).

summer valley
#

Thanks again, I think I'll just purely copy the layout from the old code and keep my new TS code nice and clean and working. Do I have to do anything to mark this question as closed?

queen willow
#

not that I'm aware of

candid rapids