Как можно решить проблему с ошибкой «Argument of type 'xxx | yyy' is not assignable to parameter of type 'never'»?

Как можно обобщить код внутри функции `f()`, чтобы избежать ошибки "Argument of type 'number | boolean' is not assignable to parameter of type 'never'" при вызове метода `p.stringify`, и чтобы эффективно обрабатывать оба типа `T1` и `T2` без явного указания условий для каждого случая?
  • 20 ноября 2024 г. 10:13
Ответы на вопрос 2
Ошибка "Argument of type 'xxx | yyy' is not assignable to parameter of type 'never'" обычно возникает, когда TypeScript не может определить, какие типы могут быть переданы в функцию, и не может найти подходящий тип для аргумента. Это часто связано с неправильной типизацией или отсутствием явного указания типов.

Чтобы обобщить код внутри функции и избежать этой проблемы, можно воспользоваться дженериками и объединением типов. Пример ниже демонстрирует, как можно сделать это:

```typescript
// Пример структуры данных и функции
type T1 = number;
type T2 = boolean;

interface Parser<T> {
    stringify(input: T): string;
}

// Пример парсера для каждого типа
const numberParser: Parser<T1> = {
    stringify: (input: T1) => `Number: ${input}`
};

const booleanParser: Parser<T2> = {
    stringify: (input: T2) => `Boolean: ${input}`
};

// Обобщенная функция, которая использует дженерик для работы с разными типами
function f<T>(parser: Parser<T>, value: T): string {
    return parser.stringify(value);
}

// Использование функции с разными типами
const result1 = f(numberParser, 42);        // "Number: 42"
const result2 = f(booleanParser, true);     // "Boolean: true"

// Пример функции, которая принимает значения любого типа из указанного объединения
function processValue<T>(value: T): string {
    if (typeof value === 'number') {
        return f(numberParser, value);
    } else if (typeof value === 'boolean') {
        return f(booleanParser, value);
    } else {
        throw new Error("Unsupported type");
    }
}

// Использование
const output1 = processValue(100); // "Number: 100"
const output2 = processValue(false); // "Boolean: false"
```

В данном примере мы:

1. Определяем два типа `T1` и `T2` с помощью дженериков.
2. Создаем интерфейс `Parser`, который определяет метод `stringify`.
3. Реализуем конкретные парсеры для каждого типа.
4. Создаем обобщенную функцию `f`, которая принимает парсер и значение, и вызывает `stringify`.
5. Функция `processValue` может быть использована для обработки значения любого из типов ожидания, использовав структуры `if-else` для определения типа.

Такой подход позволяет избежать ошибок связанности типов и типа 'never', так как TypeScript теперь может гарантировать, что передаваемые аргументы соответствуют ожиданиям функций.
Если хочется написать обобщенный код, то не надо себя сдерживать! Просто напиши обобщенный код. 

type TGen<T> = {
    parse: (s: string) => T;
    stringify: (value: T) => string;
}

function f<T>(p: TGen<T>) {
    return p.stringify(p.parse('a'));
}
Похожие вопросы