microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.19k stars 12.38k forks source link

Library method redefinition stopped working from 5.4 to 5.5 #59808

Open Glandos opened 2 weeks ago

Glandos commented 2 weeks ago

🔎 Search Terms

Duplicate identifier 'VueI18n'. Subsequent property declarations must have the same type.

🕗 Version & Regression Information

Behavior is the same with 5.7.0-dev.20240830

⏯ Playground Link

No response

💻 Code

shims-augment.d.ts:


/**
 * Overloads VueI18n interface to avoid needing to cast return value to string.
 * @see https://github.com/kazupon/vue-i18n/issues/410
 * It can be resolved with vue-i18n >= 9 (that only works with Vue 3 currently)
 */
import VueI18n from 'vue-i18n/types'
declare module 'vue-i18n/types' {
  export default class VueI18n {
    t (key: Path, locale: Locale, values?: Values): string
    t (key: Path, values?: Values): string
  }
}

declare module 'vue/types/vue' {
  interface Vue {
    $t: typeof VueI18n.prototype.t
  }
}

Excerpt of vue-i18n/types/index.d.ts:


declare namespace VueI18n {
  type Path = string;
  type Locale = string;
  type FallbackLocale = string | string[] | false | { [locale: string]: string[] }
  type Values = any[] | { [key: string]: any };
  type Choice = number;
  interface MessageContext {
    list(index: number): unknown
    named(key: string): unknown
    linked(key: string): VueI18n.TranslateResult
    values: any
    path: string
    formatter: Formatter
    messages: LocaleMessages
    locale: Locale
  }
  type MessageFunction = (ctx: MessageContext) => string;
  type LocaleMessage = string | MessageFunction | LocaleMessageObject | LocaleMessageArray;
  interface LocaleMessageObject { [key: string]: LocaleMessage; }
  interface LocaleMessageArray { [index: number]: LocaleMessage; }
  interface LocaleMessages { [key: string]: LocaleMessageObject; }
  type TranslateResult = string | LocaleMessages;
}

declare class VueI18n {
  constructor(options?: VueI18n.I18nOptions)

  readonly messages: VueI18n.LocaleMessages;
  readonly dateTimeFormats: VueI18n.DateTimeFormats;
  readonly numberFormats: VueI18n.NumberFormats;
  readonly availableLocales: VueI18n.Locale[];

  locale: VueI18n.Locale;
  fallbackLocale: VueI18n.FallbackLocale;
  missing: VueI18n.MissingHandler;
  formatter: VueI18n.Formatter;
  formatFallbackMessages: boolean;
  silentTranslationWarn: boolean | RegExp;
  silentFallbackWarn: boolean | RegExp;
  preserveDirectiveContent: boolean;
  pluralizationRules: VueI18n.PluralizationRulesMap;
  warnHtmlInMessage: VueI18n.WarnHtmlInMessageLevel;
  postTranslation: VueI18n.PostTranslationHandler;
  sync: boolean;

  t(key: VueI18n.Path, values?: VueI18n.Values): VueI18n.TranslateResult;
  t(key: VueI18n.Path, locale: VueI18n.Locale, values?: VueI18n.Values): VueI18n.TranslateResult;
}

declare module 'vue/types/vue' {
  interface Vue {
    readonly $i18n: VueI18n & IVueI18n;
    $t: typeof VueI18n.prototype.t;
  }
}

🙁 Actual behavior

Capture d’écran_2024-08-30_17-26-45

Capture d’écran_2024-08-30_17-28-08

On top of that, since $t is in error, my whole code base reports an error whenever it uses the returned value of $t as a string.

🙂 Expected behavior

No error were reported with 5.4.5

Additional information about the issue

I apologize if it's a feature, not a bug, but I wasn't able to find any info on this in the release notes.

I know that narrowing is not safe here, I'm wondering why it was allowed with old Typescript, and not anymore.

RyanCavanaugh commented 2 weeks ago

We need a shorter repro here if we're going to investigate something that's observably more-correct

Glandos commented 1 week ago

OK, I've managed to set something up at https://github.com/Glandos/test-ts-55/ There are maybe too much dependencies, but it's a strip down version of my project. With dependencies in yarn cache with LFS. Maybe there's also too much .d.ts. Tell me if it's minimal enough :)

RyanCavanaugh commented 1 week ago

20-30 lines in three files (plus config) or less is the target here; that's all that should be needed to demonstrate the described problem if it's actually a bug