I have a HeaderComponent
that takes an object of form {title: string, short_desc: string}
as its input property.
@Component({
selector: 'header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
@Input() data: { title: string, short_desc: string };
constructor() { }
ngOnInit() { }
}
Here is how I define data that will be passed to HeaderComponent
:
@Component({
templateUrl: './my-custom.component.html',
styleUrls: ['./my-custom.component.scss']
})
export class MyCustomComponent implements OnInit {
public headerData: {title: string, short_desc: string};
constructor() {
this.headerData = {
title: 'Settings Page',
short_desc: 'Update your settings',
}
}
ngOnInit() { }
}
Now, I need to use HeaderComponent
in quite a few components. So I created a file header-data.ts
which looks like this:
export interface HeaderData {
title: string;
short_desc: string;
}
In order to make HeaderComponent
work, in every component that uses it, I need to import HeaderData
interface. This can sometimes look ugly and can break, when I decide to restructure my application.
My question is: how to use HeaderData
interface without need for ugly nested imports like ../../../../hero-data.ts
, or in-line object type definitions. Or maybe what I do is not the best way to go about this problem here?
An interface is a way to define a contract on a function with respect to the arguments and their type. Along with functions, an interface can also be used with a Class as well to define custom types. An interface is an abstract type, it does not contain any code as a class does.
If it is used by components outside product-list , it is reasonable to put it into 'shared'. If it's not, it may be inside product-list. component.
The Interface describes either a contract for a class or a new type. It is a pure Typescript element, so it doesn't affect Javascript. A model, and namely a class, is an actual JS function which is being used to generate new objects.
You apparently noticed how you usually import multiple Angular classes from @angular/... modules in a single line. That's is the Barrel feature. Please look at the Barrel file description in the Angular docs.
While reading that text, you have to understand the difference between a JavaScript module and an Angular module. The former is a source file, the latter is a class decorated with @NgModule.
Since interface
is not a JavaScript notion, but an abstraction in TypeScript, it is needed only in the editor and during transpilation. Module loaders don't use interface file declarations. So you can use a trick and declare it as a TypeScript definition.
Rename your file to header-data.d.ts, and use the word declare
instead of export
like the following.
declare interface HeaderData {
title: string;
short_desc: string;
}
So TypeScript will be able to find the HeaderData
name at design time. This trick relies on the "**/*.d.ts"
line in the "include"
array in the tsconfig.spec.json
file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With