How to use Typescript with libraries like Ampersand.js that parse configs to build prototypes

折月煮酒 提交于 2019-12-06 14:55:55

Here's what I came up with- first I stubbed out the Ampersand.js module definition. I've never used Ampersand, so just going off their docs:

declare module ampersand {
    interface AmpersandState {
        // todo...
    }

    interface AmpersandCollection {
        // todo...
    }

    interface ModelExtendOptions {
        parse?: boolean;
        parent?: AmpersandState;
        collection?: AmpersandCollection;
    }

    interface ModelSaveOptions {
        patch?: boolean;
    }

    interface AmpersandModel<TProps> {
        save: (attrs?: TProps, options?: ModelSaveOptions) => void;
        // todo:  fetch, destroy, sync, etc...
    }

    interface AmpersandModelConstructor<TProps, TModel extends AmpersandModel<any>> {
         new (attrs: TProps, options?: ModelExtendOptions): TModel;
    }   

    interface ExtendOptions {
        props?: {};
        session?: {};
        derived?: {};
    }   

    interface AmpersandModelStatic {
        extend: <TProps, TModel extends AmpersandModel<any>>(options: ExtendOptions) => AmpersandModelConstructor<TProps, TModel>;
    }
} 

declare var AmpersandModel: ampersand.AmpersandModelStatic;

Below is how you would use the above ampersand module definition to define your own interfaces, etc.

Due to limitations in what Typescript generics and inheritance can do you'll need to create two interfaces for every model type: one for it's properties and a second that combines the properties and the ampersand base model:

// interface for person properties...
interface PersonProps {
    firstName: string;
    lastName: string;
}

// interface to tie everything together...
interface PersonModel extends PersonProps, ampersand.AmpersandModel<PersonProps> {
}

// use AmpersandModel's extend method...
var Person = AmpersandModel.extend<PersonProps, PersonModel>({ props: { firstName: 'string', lastName: 'string' } });

// at this point you now have full intellisense/type checking for the constructor and properties.
var me = new Person({ firstName: 'Jeremy', lastName: 'Danyow' });
me.firstName = 'Ron';  // yes!
me.eyeColor = 'Brown'; // compile error!

[Here's a link to run the code in the typescript playground]

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!