#typescript
Вопрос:
У меня есть следующий метод:
getGeometry(): { polygon: Polygon; circle: Circle } {
let geometry = { circle: null, polygon: null };
if (this.geometry instanceof CircleRegistryPath) {
if (!this.geometry.circle) return this.toastr.error('Не выбрана геометрия объекта');
geometry.circle = this.geometry.circle;
}
if (this.geometry instanceof PolygonRegistryPath || this.geometry instanceof RectangleRegistryPath) {
if (!this.geometry.polygons.length) return this.toastr.error('No geometry');
const [polygon, ...rest] = this.geometry.polygons;
const firstVertex = polygon.Vertexes[0];
if (!pointsAreEqual(firstVertex, polygon.Vertexes[polygon.Vertexes.length - 1])) polygon.Vertexes.push(firstVertex);
geometry.polygon = polygon;
}
return geometry;
}
Я пытаюсь прояснить этот метод, но, как вы заметили, он возвращает значение false в случае ошибки и { polygon: Polygon; circle: Circle }
в других случаях.
Как проверить данные и сделать этот метод понятным?
Моя вторая попытка:
getGeometry(geometry: CircleRegistryPath | PolygonRegistryPath | RectangleRegistryPath): { polygon: Polygon; circle: Circle } {
const data = { circle: null, polygon: null };
if (geometry instanceof CircleRegistryPath) {
if (!geometry.circle) throw '';
data.circle = geometry.circle;
}
if (geometry instanceof PolygonRegistryPath || geometry instanceof RectangleRegistryPath) {
if (!geometry.polygons.length) throw '';
const [polygon, ...rest] = geometry.polygons;
const firstVertex = polygon.Vertexes[0];
if (!pointsAreEqual(firstVertex, polygon.Vertexes[polygon.Vertexes.length - 1])) polygon.Vertexes.push(firstVertex);
data.polygon = polygon;
}
return data;
}
Комментарии:
1. Может быть, лучше выбросить исключение вместо возврата this.toastr?
2. Нет, мне не нужна ошибка в ответе. Я попробовал второй способ, посмотрите на мой квестон, пожалуйста
3. Я не понимаю, зачем вам нужна проверка данных, когда они у вас есть, лучший способ проверить их, когда вы их получите, а также с помощью типов. другими словами
instanceof CircleRegistryPath
, и!geometry.circle
как вы этого достигли ?
Ответ №1:
Полиморфизм и деструктурирование, вероятно, помогут получить чистый код.
type Circle = {
x: number,
y: number,
r: number
} | null |undefined;
type Vertex = {
x: number,
y: number
} | null | undefined
type Polygon = {
Vertexes: Vertex[]
} | null | undefined;
type Data = {
circle?: Circle,
polygons?: Polygon,
} | null;
class Geometry {
data: Data = null;
constructor(data: Data){
this.data = data
}
getData(): Data {
return this.data as Data;
}
}
class CircleRegistryPath extends Geometry {
circle: Circle;
constructor(init: Circle){
super({circle: init});
}
}
class PolygonRegistryPath extends Geometry{
polygons: Polygon;
constructor(init: Polygon){
super({polygons: init});
}
}
class RectangleRegistryPath extends Geometry{
polygons: Polygon;
constructor(init: Polygon){
super({polygons: init});
}
}
const pointsAreEqual = (a: Vertex, b: Vertex):boolean =>{
if (!a || !b) return false;
return a.x === b.x amp;amp; a.y === b.y;
}
const closePath = (polygon: Polygon): Polygon => {
if (polygon?.Vertexes.length === 0) return polygon;
const firstVertex = polygon?.Vertexes[0];
const lastVertex = polygon?.Vertexes[polygon?.Vertexes.length - 1];
if (!pointsAreEqual(firstVertex, lastVertex) amp;amp; firstVertex)
polygon?.Vertexes.push( {x: firstVertex.x, y: firstVertex.y });
return polygon;
}
class GeometryObject {
getGeometry( geometry: Geometry): Data {
if (geometry instanceof PolygonRegistryPath
|| geometry instanceof RectangleRegistryPath) {
closePath(geometry.polygons);
}
return { circle: null, polygons: null, ...geometry.data };
}
}
const c = new CircleRegistryPath({x:10, y:20, r:30})
const r = new RectangleRegistryPath(
{Vertexes: [
{ x:0, y:0},
{ x:50, y:0},
{ x:50, y:50},
{ x:0, y:50}
]}
)
const p = new PolygonRegistryPath(
{Vertexes: [
{ x:0, y:0},
{ x:50, y:0},
{ x:50, y:50},
]}
)
const go = new GeometryObject();
console.log(go.getGeometry(c));
console.log(go.getGeometry(r));
console.log(go.getGeometry(p));