简体   繁体   中英

TypeScript - How to correlate one function parameter with another?

Let's imagine I have the following function that will create something using a template (tpl) and the template's params (params):

create(tpl, params) {
  // create something
}

I have 2 templates, so I will use an enum to define it:

enum TEMPLATE {
  TPL1 = "TPL1",
  TPL2 = "TPL2",
}

And each of those templates have a set of parameters: some params are common to both templates, some params are specific:

interface BaseParamsTPL {
  name: string;
  topic: string;
}

interface ParamsTPL1 extends BaseParamsTPL {
  URL: string;
}

interface ParamsTPL2 extends BaseParamsTPL {
  productId: number;
  price: number;
}

Now, what I want is my "create" function to have "linked" parameters, meaning that if I pass TEMPLATE.TPL1, I want the "params" object to match "ParamsTPL1", and same for TPL2. So, something like the following should fail:

const myCreation = create(TEMPLATE.TPL2, {
  name: "something",
  topic: "random",
  URL: "http://loin.labas.com"
}) // should fail because the "tpl" passed in doesn't match the "params" object.

I was thinking of something like that:

create<T extends keyof typeof TEMPLATE>(tpl: T, params: `Params${T}`) {
  // create something
}

But it doesn't seems to be the good way of doing it.

Any idea how I can achieve that?

Function overloading will do this:

enum TEMPLATE {
    TPL2,
    TPL1
}

interface BaseParamsTPL {
  name: string;
  topic: string;
}

interface ParamsTPL1 extends BaseParamsTPL {
  URL: string;
}

interface ParamsTPL2 extends BaseParamsTPL {
  productId: number;
  price: number;
}

function create(template: TEMPLATE.TPL1, options: ParamsTPL1): any;
function create(template: TEMPLATE.TPL2, options: ParamsTPL2): any;
function create(template: TEMPLATE, options: any): any {

}


// TS transpiler won't allow this because of the typing in our function overload
const myCreation = create(TEMPLATE.TPL2, {
  name: "something",
  topic: "random",
  URL: "http://loin.labas.com"
})

const myCreation2 = create(TEMPLATE.TPL1, {
  name: "something",
  topic: "random",
  URL: "http://loin.labas.com"
})

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