0

I defined an array of an interface

interface Converter<T = Buffer> {
  name: string;
  uuid: CUUID;
  decode: (value: Buffer) => T;
}

type Converters = ReadonlyArray<Converter<any>>;

but for my usecase I need to cast every item in that array using a const assertion:

const infoConverter = {
  name: "info",
  uuid: "180a",
  decode: (v: Buffer) => v.toString()
} as const;

const pressureConverter = {
  name: "pressure",
  uuid: "1810",
  decode: (v: Buffer) => v.readInt32BE(0)
} as const;

const converters = [infoConverter, pressureConverter];

I would not mind doing that, but I am writing a library and users of that library are providing that array. So in order for the library to work properly I will have to ask the users to use a const assertion whenever they work with it, which is not quite optimal.

For me, it would be great if the could just provide the library with their data and I could automatically do a const assertion.

So I have this class

class Service<C extends Converters> {
  private converters?: Converters;

  constructor(converters?: C) {
    this.converters = converters;
  }
}

and I wonder if there is a way I could do something like this:

class Service<C extends Converters> {
  private converters?: EveryItemIsAConst<Converters>;

  constructor(converters?: C) {
    this.converters = converters as EveryItemIsAConst<C>;
  }
}

and the users could just do

const infoConverter = {
  name: "info",
  uuid: "180a",
  decode: (v: Buffer) => v.toString()
};

const pressureConverter = {
  name: "pressure",
  uuid: "1810",
  decode: (v: Buffer) => v.readInt32BE(0)
};

const converters = [infoConverter, pressureConverter];

const service = new Service(converters)

and the EveryItemIsAConst would make sure as const is applied to every item in the converters array.

2
  • 2
    The problem with the code at the end is that by the time you get to new Service(converters) the compiler has already widened the type of converters[0].name and converters[1].name to string, and there's no way to get it back. There are different ways to keep string literals narrow but all of them will require users of Service to do something. e.g., const infoConverter = {...} as const, or const infoConverter = asConverter({}) (for an appropriate asConverter() function). Commented Sep 8, 2019 at 19:42
  • Alright, thank you so much! Commented Sep 9, 2019 at 8:39

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.