keepByteOrderMarks

tcmts.core.ts.keepByteOrderMarks · #w7mjn55d · term · runs anywhere

TypeScript 7's API decodes each string it reads (a file's text, a literal's) with a TextDecoder that drops a leading byte order mark, so the literal "\uFEFFx" would read as "x". Put it back, in the decoder's class (the API and each program have one).

export function keepByteOrderMarks(decoder: object): void {
  const proto = Object.getPrototypeOf(decoder) as { decode(input?: ArrayBufferView | ArrayBuffer, options?: unknown): string; tcmKeepsBom?: true };
  if (proto.tcmKeepsBom) return;
  const decode = proto.decode;
  proto.decode = function (input, options) {
    const s = decode.call(this, input, options);
    if (!input || s.charCodeAt(0) === 0xfeff) return s;
    const bytes = ArrayBuffer.isView(input) ? new Uint8Array(input.buffer, input.byteOffset, input.byteLength) : new Uint8Array(input);
    return bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf ? "\uFEFF" + s : s;
  };
  proto.tcmKeepsBom = true;
}

used by