简体   繁体   中英

Define and extend custom types in TypeScript

I am trying to define custom types in TypeScript with some additional extension methods, also want to allow other uses of my library to extend this type as well.

Want to implement the toJson method and more utility functions, I tried to do that by creating two files: domain.d.ts with this code:

export type TermOperator = '=' | '>' | '<' | '!=' | '<=' | '>=' | 'in' | 'not in' | 'like';
export type DomainOperator = '&' | '|' | '!';

export type Term = [left: string, operator: TermOperator, right: string | number | Date | EnumType | undefined | boolean];
export type ScalarDomain = [...Array<DomainOperator | Term>];

export interface Domain extends Array<ScalarDomain | Domain | DomainOperator | Term>
{
    toJson(): string;
    flat(): [string | number | Date | EnumType | boolean | undefined];
    parse(): void;
}

and tried to add new file domain.extension.ts with the following code:

Domain.prototype.toJson = function (){ return 'json object'; }

But I am getting errors such as:

Error TS2693 (TS) 'Domain' only refers to a type, but is being used as a value here.

don't know exactly how to achieve this, as I am a beginner in JavaScript.

For more context, here is how I am planning to use this code:

const term1: Term = ['name', '=', 'amine'];
const term2: Term = ['age', '>', 25];
const term3: Term = ['address', 'like', 'eloued'];

const domain1: Domain = ['|', term1, term2, '&', term3];
const domain2: Domain = ['&', term1, term2, '&', ['city', '=', 'Malaga']];
const domain3: Domain = [domain1, domain2];

const jsonStr: string = domain3.toJson();

A type cannot add functionality.

All that this does:

const domain1: Domain = ['|', term1, term2, '&', term3];

is tell Typescript that domain1 is expected to be of type Domain , and if it's not then a type error will be shown. It does not, and cannot , change the features on the array that is being assigned to this variable.

Imagine all type annotations were removed. Would your code work? Because that's exactly what happens when your code executes.


If you want to provide additional methods to this array, you would typically wrap that value in a class that allows you declare those other methods.

For example:

export class Domain {
    constructor(public terms: ScalarDomain) {}

    toJson() {
      return JSON.stringify(this.terms)
    }

    flat() {
      return this.terms.flat()
    }

    parse() {
      console.log('implete parse here')
    }
}

Which you would use like:

const term1: Term = ['name', '=', 'amine'];
const term2: Term = ['age', '>', 25];
const term3: Term = ['address', 'like', 'eloued'];

const domain1 = new Domain(['|', term1, term2, '&', term3]);
domain1.toJson() // fine

See playground


Or a more functional approach would be to create functions that accept your data and do things with them.

function domainToJson(domain: Domain) { return JSON.stringify(domain) }
function domainFlat(domain: Domain) { return domain.flat() }

const term1: Term = ['name', '=', 'amine'];
const term2: Term = ['age', '>', 25];
const term3: Term = ['address', 'like', 'eloued'];

const domain1: Domain = ['|', term1, term2, '&', term3]
domainToJson(domain1) // fine

See playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM