По сути, мне нужна функция, которая клонирует (т.е. глубоко копирует) объекты, которые имеют некоторые общие свойства.«Общее свойство» - это, по сути, просто тег с именем op
для операции.Итак, ранее у меня был какой-то код, набранный с использованием Flow:
export function cloneExpr<E: Expr>(exp: E): E {
if (exp.op === POINT) {
return ((expr.makePoint(exp.p, exp.x, exp.y):any):E);
} ... etc
}
, где Expr
- это объединение множества таких вещей, как Point
, Line
и т. Д., Каждый из которых имеет этот op
поле.Кастинг несколько уродливый, но по крайней мере это работает;т.е. если я cloneExpr
объект набрал Point
, возвращаемый объект набрал Point
без необходимости предоставления дополнительной информации о наборе.
Теперь я хотел бы перейти на Typescript, но у меня естькуча проблем.Тяжелое литье return ((exp as any) as Point)
работает в вакууме, но мой охранник типов продолжает терять информацию, поэтому, например, я не могу получить поле x
из Точки exp
, не провалив проверку ввода.Чтобы заставить typeguard работать, я пробовал много вариантов типов функций, таких как:
function cloneExpr<T extends Expr>(exp: T): T
, где Expr
- это что-то вроде Point | Line
.
function cloneExpr<T extends IsExpr>(exp: T): T
где IsExpr
- это интерфейс, который я определил только с полем op
.
function cloneExpr(exp: Expr): Expr
, который я пробовал, но ясно, что я никогда не верну правильный тип ввода.
Так что либо я не получаю typeguard, либо тип возвращаемого значения не тот конкретный тип, который я ввел.Я также попытался переопределить объекты, используя интерфейсы, а затем предоставил определяемую пользователем защиту типа и что-то еще, но безрезультатно.
Как правильно сделать это в Typescript?Спасибо за тонну.