Сбой защиты типа при использовании значения, введенного объединением, для реквизитов

#typescript

#typescript

Вопрос:

У меня есть приведенный ниже фрагмент кода:

 interface PluginHook {
    onStoreCreated?: (p1: number) => void;
    onModel?: (p2: string) => void;
}

interface MyPlugin extends PluginHook {
    config?: Record<string, unknown>;
}

interface Bag {
    forEachPlugin: <Hook extends keyof PluginHook>(
        method: Hook,
        fn: (content: NonNullable<PluginHook[Hook]>) => void
    ) => void
}

type Method = keyof PluginHook;

function fn(p: NonNullable<PluginHook[Method]>) { }

const plugins: MyPlugin[] = [];

const bag: Bag = {
    forEachPlugin(method, fn): void {
        for (const plugin of plugins) {
            // const mmthod: keyof PluginHook = 'onStoreCreated';
            const hook = plugin[method]
            if (hook) {
                fn(hook)
            }
        }
    },
}

  

В forEachPlugin , защита типа для hook , похоже, не работает. Перехват все еще не определен, поэтому я не могу передать его в значение, не подлежащее заполнению.

Ранее я писал подобный код и открыл проблему на TypeScript.

 // ...
const bag: Bag = {
    forEachPlugin(method, fn): void {
        for (const plugin of plugins) {
            if (plugin[method]) {
                fn(plugin[method])
            }
        }
    },
}
  

Но они сказали, что это не ошибка, если я перейду на это:

 const bag: Bag = {
    forEachPlugin(method, fn): void {
        for (const plugin of plugins) {
            const hook = plugin[method]
            if (hook) {
                fn(hook)
            }
        }
    },
}
  

В некоторых случаях это срабатывало, но в моем случае также не сработало. Я думаю, что это тоже была ошибка. Если нет, есть ли какой-либо обходной путь для решения этой проблемы? Полный код на игровой площадке.

Заранее спасибо!

Комментарии:

1. Использование const hook = plugin[method] ?? undefined; работает, но я не знаю почему

2. Спасибо!!! Это сработало как шарм. Но я также хочу знать, почему.