Комментарии 4
Совпадение или нет, но недавно как раз изучал сужение типов.
И появился вопрос.
Как сузить тип второго и/или последующего независимого аргумента функции в зависимости от типа первого аргумента?
Пример
То же самое с оверлоадом казалось бы раз мы сузили тип shape до Square, почему TypeScript не может подсказать что param это SquareParam, ведь кажется теперь-то у него для этого все возможности есть поскольку задекларированы возможные комбинации параметров? Или нет?
И появился вопрос.
Как сузить тип второго и/или последующего независимого аргумента функции в зависимости от типа первого аргумента?
Пример
enum ShapeType {
Circle = 'circle',
Square = 'square',
};
type SquareColor = 'black' | 'white';
type CircleColor = 'red' | 'blue';
type Circle = {
type: ShapeType.Circle;
color: CircleColor;
radius: number;
}
type Square = {
type: ShapeType.Square;
color: SquareColor;
sideLength: number;
}
type Shape = Circle | Square;
const isSquare = (shape: Shape): shape is Square => {
return shape.type === ShapeType.Square;
}
const repaintShape = (shape: Shape, param: SquareColor | CircleColor): Shape => {
if (isSquare(shape)) {
// param всё ещё CircleColor | SquareColor хоть shape теперь верно Square
// понятно что у TS нет возможности догадаться
// какой тип param нам нужен, как эту проблему решить?
}
}
То же самое с оверлоадом казалось бы раз мы сузили тип shape до Square, почему TypeScript не может подсказать что param это SquareParam, ведь кажется теперь-то у него для этого все возможности есть поскольку задекларированы возможные комбинации параметров? Или нет?
function repaintShape(shape: Circle, param: CircleColor): Circle
function repaintShape(shape: Square, param: SquareColor): Square
function repaintShape(shape: Shape, param: CircleColor | SquareColor): Shape {
if (isSquare(shape)) {
// shape теперь Square но param всё ещё CircleColor | SquareColor
}
}
В вашем случае typescript не может связать shape
и param
, для него это разные вещи и он понятия не имеет что именно вы хотите с ними делать. У вас буквально указано, что аргументами могут быть Shape
и вот такие цвета, поэтому typescript и допускает вызов Circle
с SquareColor
Если вы хотите именно связать shape
и param
на уровне вызова функции, чтобы при передаче Circle
в качестве param
можно было указывать лишь CircleColor
, а при Square
только SquareColor
, то могу рекомендовать сделать это через generic
const repaintShape = <T extends Shape>(
shape: T,
param: T['color']
): Shape => {
// ...
};
В таком случае любая Shape будет требовать свой цвет
Должно быть: «И последнее слово о сужении по истинности: логические отрицания с ! отфильтровываются из отрицательных ветвей.»
Вместо: «Напоследок, рассмотрим пример использования логического оператора „НЕ“:»
Вместо: «Напоследок, рассмотрим пример использования логического оператора „НЕ“:»
Странная тема про сужение. Странна тем, что solid подход и не встретил бы этих проблем имхо
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Карманная книга по TypeScript. Часть 3. Сужение типов