Search code examples
typescriptinterfaceaureliadefinition

How to declare interfaces which are used by multiple view models


I'm just getting started with Aurelia & Typescript and am looking for some advice on best practices. Here's the base code which basically describes a list of products separated into a parent products view which consists of detailed product-card views:

products.html

<template>
    <require from="./product-card"></require>

    // ...

    <div repeat.for="product of products" class="product-cards">
        <product-card product.bind="product"></product-card>
    </div>

    // ...
</template>

products.ts

export class Products {
    public products: Product[] = [
        {
            name: 'Salt',
            price: 10
        },{
            name: 'Orange Juice',
            price: 12
        }
    ];
}

product-card.html

<template>
    Name: ${product.name}
    Price: ${product.price}
</template>

product-card.ts

import {bindable} from 'aurelia-framework';

export class ProductCard {
    @bindable product: Product;
}

All those files are in the same directory and the Product interface which is used in product.ts & product-card.ts is as simple as...

export interface Product {
    name: string;
    price: number;
}

This basically works except for the fact that neither products.ts nor product-card.ts actually know the Product interface with the code above.

Here's how I'd have solved this:

  • Create a dedicated definition file product.d.ts in the same folder as all the other files
  • Import the definition file in products.ts as well as in product-card.ts using import {Product} from './product';

Is creating a dedicated definitions file for a simple interface which is shared by multiple view models considered good/best practice or are there any other ways to solve this? Also is it ok to put the *.d.ts inside the same folder as the sources or should this be somewhere else?


Solution

  • Aurelia encourage using the MVVM (Model-View-ViewModel) design pattern.

    • products.html is your View
    • products.ts is your ViewModel
    • product.d.ts is your Model, that can be included/used in more that one ViewModel

    I prefer call product-model.ts, but the name is with you. It is common to need to create a service class (eg: product-service.js) that will make the requests to the server and sometimes some business logic, in this case you can include the model in this service class. (in TypeScript its common put more that one class in file)

    You can see more tips for project structure in this great blog: https://blog.ashleygrant.com/2016/04/19/suggestions-for-structuring-a-large-aurelia-application/

    In this example you don't need create the ViewModel "product-card.ts", you can create only the view: http://aurelia.io/hub.html#/doc/article/aurelia/templating/latest/templating-custom-elements/1

    Replay to your question yes, it's ok put the model in a separate file and in same folder.