Как проверить данные в методе и прояснить функцию?

#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));