Home > OS >  How do I get a dynamic type from a dynamic array in typescript?
How do I get a dynamic type from a dynamic array in typescript?

Time:12-11

I've searched for a solution already and found const assertions but Typescript gives me a type error that I can only use const assertions on certain types... Probably referring to that the array I want to assert is not set in the same file but rather will be set by the user who will be using my module. To explain what I mean I have some code below.

The following code block is the file HighLight.ts for example.

type Languages = "javascript" | "typescript" | "json" | "java" | "kotlin" | "python";

export default class HighLight {
  private languages: Languages | Languages[];

  constructor({ languages }: { languages: Languages | Languages[] }) {
    this.languages = <const>languages;
  }
}

And I import it in the index.ts file

import HighLight from "HighLight.ts";

new HighLight(["javascript", "typescript"])

To give some more context, I want to create a module that can highlight code using highlight.js and have it as a pure string which you can print to the console, essentially a port of highlight.js for nodejs but purely for console applications.

Because I want my implementation to import all languages only as needed (like highlight.js) the user has to provide a list of languages they plan on highlighting later on. I've figured out the importing part already but I haven't attached that code as I think it is irrelevant to this problem.

With that out of the way, I wanted to create a highlight method which takes in the code and the language. It would be nice if languages is restricted to only the languages you've given the constructor when creating an instance. What I thought to be an easy task with a const assertion turned out to be hard. A const assertion in this scenario doesn't work as the array/string is unknown at the moment but later set by the user when calling the constructor... I also noticed that if the array is statically typed but in a different file a const assertion also does not work sadly.

Is there a different way of getting that type for the highlight method?

CodePudding user response:

type Languages = "javascript" | "typescript" | "json" | "java" | "kotlin" | "python";

export default class HighLight<L extends Languages> {
  private languages: L | L[];

  constructor({ languages }: { languages: L | L[] }) {
    this.languages = languages;
  }
}

let l = new HighLight({languages: 'javascript'})
//  ^? let l: HighLight<"javascript">
  • Related