#typescript
#typescript
Вопрос:
Я хочу сузить тип на основе свойства класса при вызове array .filter
или .find
class Square {
type: "square";
constructor() {
this.type = "square";
}
}
class Circle {
type: "circle";
constructor() {
this.type = "circle";
}
}
const objects = [
new Circle(),
new Square(),
new Circle(),
new Square(),
];
// I want `circles` to be Circle[], not (Circle | Square)[]
const circles = objects.filter(o => o.type === "circle");
// I want `square` to be Square | undefined, not Circle | Square | undefined
const square = objects.find(o => o.type === "square");
Возможно ли это в Typescript?
Комментарии:
1. Какую ES-версию вы должны использовать? какие-либо ограничения или будет ли работать ES2019? (Я спрашиваю, потому что для игровой площадки установлено значение ES2017).
2.
objects.filter((o): o is Circle => o.type === "circle");
Ответ №1:
Вы можете сделать это с помощью функций защиты типов. Вот пример с функциями защиты типов, определенными заранее:
function isSquare(obj: {type: string}): obj is Square {
return obj.type === "square";
}
function isCircle(obj: {type: string}): obj is Circle {
return obj.type === "circle";
}
// ...
// I want circles to be Circle[]
const circles = objects.filter(isCircle);
// I want square to be Square | undefined
const square = objects.find(isSquare);
… но они также могут быть встроенными:
// I want circles to be Circle[]
const circles = objects.filter((obj): obj is Circle => obj.type === "circle");
// I want square to be Square | undefined
const square = objects.find((obj): obj is Square => obj.type === "square");
Комментарии:
1. Это работает, спасибо. Таким образом, typescript не может автоматически определять тип на основе значения свойства? Поскольку тип
type
свойства является статической строкой (нетstring
) Я думал, что Typescript сможет обнаружить его автоматически.2.@Owl — я был немного удивлен, что создание
type
readonly
не позволило сделать правильный вывод, но существуют ограничения на то, что делает компилятор TypeScript, из-за того, сколько времени потребуется для этого (а не только может ли он это сделать). Тем не менее, я был удивлен. Я не могу с уверенностью сказать, что другого способа нет (TypeScript чрезвычайно сложен), но функции защиты типов работают. 🙂