You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
В разделе "Обобщения / Модификаторы вариантности параметров типа in и out" говорится:
in указывает, что параметр типа ковариантен, а out контрвариантен. Но стоит сделать акцент на том, что с помощью этих модификаторов невозможно изменить правила по которым TypeScript производит вычисления совместимости, а можно лишь их конкретизировать.
На самом же деле, модификаторы вариантности могут сужать вариантность, но не могут её расширять или менять на противоположную. То есть, если параметр типа автоматически выводится ковариантным, мы можем сделать его инвариантным, но не можем сделать бивариантным или контравариантным. Бивариантному параметру можно установить любую желаемую вариантность.
Пример:
// Здесь параметр T является бивариантнымtypeExample<T>={}declareletvsub: Example<1>declareletvsuper: Example<1|2>// Присваивание в обе стороны возможноvsub=vsupervsuper=vsub
// Здесь параметр T является контравариантнымtypeExample<inT>={}declareletvsub: Example<1>declareletvsuper: Example<1|2>vsub=vsupervsuper=vsub// Ошибка
Если нужно, могу привести реальные примеры в которых это позволяет избежать ошибок.
The text was updated successfully, but these errors were encountered:
@bgenia а это разве не баг? Сейчас вечер и я жутко устал, но мне кажется, что компилятор просто не берет в расчет не задействованный параметр. a | b не может быть совместимым с a поскольку может быть b, который не a.
@nauchikus Это не баг, это бивариантное поведение. Незадействовааный параметр считается бивариантным, так как его тип не влияет на структурную совместимость результирующих типов. Далее я показал пример что с помощью аннотаций можно сузить вариантность такого параметра.
Вот другой пример действия аннотаций:
// Как известно, параметры методов являются бивариантными даже при включенной strictFunctionTypes// Такое поведение может приводить к ошибкамtypeExample<T>={f(arg: T): void}declareletvsub: Example<1>declareletvsuper: Example<1|2>// Присваивание в обе стороны возможноvsub=vsupervsuper=vsub
// Контравариантность можно задать искусственно с помощью аннотации intypeExample<inT>={f(arg: T): void}declareletvsub: Example<1>declareletvsuper: Example<1|2>vsub=vsupervsuper=vsub// ошибка
В разделе "Обобщения / Модификаторы вариантности параметров типа in и out" говорится:
На самом же деле, модификаторы вариантности могут сужать вариантность, но не могут её расширять или менять на противоположную. То есть, если параметр типа автоматически выводится ковариантным, мы можем сделать его инвариантным, но не можем сделать бивариантным или контравариантным. Бивариантному параметру можно установить любую желаемую вариантность.
Пример:
Если нужно, могу привести реальные примеры в которых это позволяет избежать ошибок.
The text was updated successfully, but these errors were encountered: