Как исправить ошибку файла класса машинописного текста после преобразования из java?

У меня есть класс Java, который я хочу использовать в проекте typescript. Но я попытался преобразовать его и также воспользовался помощью http://www.jsweet.org/jsweet-live-песочница/. Я очень новичок в машинописи, я разработчик Java и в настоящее время изучаю передний язык. Итак, я столкнулся с проблемой, чтобы определить ошибку. Будет очень полезно, если вы поможете мне исправить мой машинописный код.

Вот мой класс Java:

import bd.edu.seu.erp.model.exception.IncorrectSemesterError;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Semester {
    private static final String NAMES[] = {"Spring", "Summer", "Fall"};
    private static final int OFFSET = 2002;

    private static Map<Integer, Semester> semesterMap = new HashMap<>();
    private static Map<String, Semester> semesterNameMap = new HashMap<>();

    private int semesterNumber;
    private String label;

    public Semester(int semesterNumber, String label) {
        this.semesterNumber = semesterNumber;
        this.label = label;
    }

    private Semester(int semesterNumber) {
        if (semesterNumber < 1)
            throw new IncorrectSemesterError("Invalid Semester", "Semester number cannot be less than 1");
        this.semesterNumber = semesterNumber;
        this.label = NAMES[semesterNumber % NAMES.length] + " " + (semesterNumber / 3 + OFFSET);
    }

    private Semester(String semesterName) {
        this.label = semesterName;
        String[] tokens = semesterName.split("\\ ");
        if (tokens.length != 2)
            throw new IncorrectSemesterError("Invalid Semester", "Semester label has incorrect number of tokens");
        String name = tokens[0];
        int year = Integer.parseInt(tokens[1]);
        if (year < OFFSET)
            throw new IncorrectSemesterError("Invalid Semester", "Year cannot be earlier than " + OFFSET);
        int nameIndex = Arrays.asList(NAMES).indexOf(name);
        if (nameIndex < 0 || nameIndex > NAMES.length)
            throw new IncorrectSemesterError("Invalid Semester", "Name of the semester must be one of [Spring, Summer, Fall]");
        this.semesterNumber = (year - OFFSET) * 3 + nameIndex;
    }

    public static Semester of(int semesterNumber) {
        Semester semester = semesterMap.getOrDefault(semesterNumber, new Semester(semesterNumber));
        semesterMap.putIfAbsent(semester.semesterNumber, semester);
        semesterNameMap.putIfAbsent(semester.label, semester);
        return semester;
    }

    public static Semester of(String semesterName) {
        Semester semester = semesterNameMap.getOrDefault(semesterName, new Semester(semesterName));
        semesterMap.putIfAbsent(semester.semesterNumber, semester);
        semesterNameMap.putIfAbsent(semester.label, semester);
        return semester;
    }

    /*
    public static Semester of(Semester semesterObject) {
        Semester semester = semesterNameMap.getOrDefault(semesterObject.semesterNumber, new Semester(semesterObject.semesterNumber));
        semesterMap.putIfAbsent(semester.semesterNumber, semester);
        semesterNameMap.putIfAbsent(semester.label, semester);
        return semester;
    }
    */
}

Вот мой машинописный файл, который я пробовал:


export class Semester {

    static NAMES: string[] = ['Spring', 'Summer', 'Fall'];
    static OFFSET = 2002;

    static semesterMap: Map<number, Semester> = new Map();
    static semesterNameMap: Map<String, Semester> = new Map();

    private semesterNumber: number;
    private label: String;

    public constructor(semesterNumber?: number, label?: String) {
        if (((typeof semesterNumber === 'number') || semesterNumber === null) && ((typeof label === 'string') || label === null)) {
            if (this.semesterNumber === undefined) {
                this.semesterNumber = 0;
            }
            if (this.label === undefined) {
                this.label = null;
            }
            if (this.semesterNumber === undefined) {
                this.semesterNumber = 0;
            }
            if (this.label === undefined) {
                this.label = null;
            }
            (() => {
                this.semesterNumber = semesterNumber;
                this.label = label;
            })();
        } else if (((typeof label === 'string') || semesterNumber === null) && semesterNumber === undefined) {
            if (this.semesterNumber === undefined) {
                this.semesterNumber = 0;
            }
            if (this.label === undefined) {
                this.label = null;
            }
            if (this.semesterNumber === undefined) {
                this.semesterNumber = 0;
            }
            if (this.label === undefined) {
                this.label = null;
            }
            (() => {
                const tokens: string[] = label.split('\\ ');
                if (tokens.length !== 2) {
                    throw new Error('Semester label has incorrect number of tokens');
                }
                const name: string = tokens[0];
                const year: number = parseInt(tokens[1], 10);
                if (year < Semester.OFFSET) {
                    throw new Error('Year cannot be earlier than ' + Semester.OFFSET);
                }
                const nameIndex: number = Semester.NAMES.slice(0).indexOf(name);
                if (nameIndex < 0 || nameIndex > Semester.NAMES.length) {
                    throw new Error('Name of the semester must be one of [Spring, Summer, Fall]');
                }
                this.semesterNumber = (year - Semester.OFFSET) * 3 + nameIndex;
            })();
        } else if (((typeof semesterNumber === 'number'))) {
            if (this.semesterNumber === undefined) {
                this.semesterNumber = 0;
            }
            if (this.label === undefined) {
                this.label = null;
            }
            if (this.semesterNumber === undefined) {
                this.semesterNumber = 0;
            }
            if (this.label === undefined) {
                this.label = null;
            }
            (() => {
                if (semesterNumber < 1) {
                    throw new Error('Semester number cannot be less than 1');
                }
                this.semesterNumber = semesterNumber;
                this.label = Semester.NAMES[semesterNumber % Semester.NAMES.length] + ' ' + (semesterNumber / 3 + Semester.OFFSET);
            })();
        } else {
            throw new Error('invalid overload');
        }
    }

    public static of(semesterNumber?: number, semesterName?: string): Semester {
        if (typeof semesterNumber === 'number') {
            const semester: Semester = Semester.semesterMap.getOrDefault(semesterNumber, new Semester(semesterNumber));
            Semester.semesterMap.putIfAbsent(semester.semesterNumber, semester);
            Semester.semesterNameMap.putIfAbsent(semester.label, semester);
            return semester;
        }
        if (typeof semesterName === 'string') {
            const semester: Semester = Semester.semesterNameMap.getOrDefault(semesterName, new Semester(semesterName));
            Semester.semesterMap.putIfAbsent(semester.semesterNumber, semester);
            Semester.semesterNameMap.putIfAbsent(semester.label, semester);
            return semester;
        }
    }
}

Прежде всего, у меня есть путаница в конструкторе машинописного текста. Я не уверен, правильно ли я написал для множественного конструктора в java. Во-вторых, в машинописи я не нашел getOrDefault, putIfAbsent в Map. Я не понял, что тут писать.

Не могли бы вы помочь мне исправить этот машинописный код? Заранее спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
145
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

По поводу конструктора

Вы правильно догадались, что нет нескольких конструкторов, которые вы привыкли иметь в Java (иначе говоря, перегрузка конструктора). У вас есть только один конструктор в TypeScript, и вам нужны необязательные параметры.

В вашем случае semesterNumber и label могут быть либо неопределенными, либо числом/строкой, проверка типа не требуется.

Способ проверки того, «что было передано», вам не нужно так много проверок в одном операторе if. Взгляните на следующий ответ здесь: https://stackoverflow.com/a/44017547/8745384

Что касается карты

Эквивалентом «putIfAbsent» является простой «набор (ключ, значение)».

Semester.semesterMap.set(semester.semesterNumber, semester);

Для getOrDefault вы можете написать

const semester: Semester = Semester.semesterMap.get(semesterNumber) || new Semester(semesterNumber);

Он делает то же самое, что я описал ранее для оператора if. Проверьте, является ли нуль ИЛИ неопределенным ИЛИ пустым, если это так, выполните новый семестр (...).

Надеюсь, я смог помочь. Недавно я тоже перешел с Java на TypeScript, так что, возможно, есть лучший способ, чем я описал.

Ответ принят как подходящий

У меня тоже есть опыт работы с Java, но старше. ;-)

Некоторые советы:

  • Выберите undefined или null, но не используйте оба. В приведенном ниже примере я использую undefined;
  • В модулях статические члены могут быть заменены простыми переменными;
  • Предпочитайте interface нескольким необязательным параметрам;
  • Ваш IIFE ((() => { … }();) бесполезен;
  • Не объявляйте тип, когда достаточно логического вывода;
  • Отдавайте предпочтение примитивным типам (string вместо String).

Вот пример:

const NAMES = ['Spring', 'Summer', 'Fall'];
const OFFSET = 2002;

const numberMap = new Map<number, Semester>();
const labelMap = new Map<string, Semester>();

export interface SemesterOptions {
    semesterNumber?: number
    label?: string
}

export class Semester {
    private semesterNumber: number;
    private label: string;

    constructor({ semesterNumber, label }: SemesterOptions) {
        if (semesterNumber === undefined) {
            if (label === undefined) {
                throw new Error('invalid options');
            }
            const parsed = parseLabelToSemesterOptions(label);
            semesterNumber = parsed.semesterNumber;
            label = parsed.label;
        } else if (label === undefined) {
            if (semesterNumber < 1) {
                throw new Error('Semester number cannot be less than 1');
            }
            label = NAMES[semesterNumber % NAMES.length] + ' ' + (semesterNumber / 3 + OFFSET);
        }

        this.semesterNumber = semesterNumber;
        this.label = label;
    }


    static ofNumber(semesterNumber: number): Semester {
        let semester = numberMap.get(semesterNumber);
        if (!semester) {
            semester = new Semester({ semesterNumber });
            numberMap.set(semester.semesterNumber, semester);
            if (!labelMap.has(semester.label)) {
                labelMap.set(semester.label, semester);
            }
        }
        return semester; 
    }

    static ofLabel(label: string): Semester {
        let semester = labelMap.get(label);
        if (!semester) {
            semester = new Semester({ label });
            labelMap.set(semester.label, semester);
            if (!numberMap.has(semester.semesterNumber)) {
                numberMap.set(semester.semesterNumber, semester);
            }
        }
        return semester; 
    }
}

function parseLabelToSemesterOptions(labelToParse: string): Required<SemesterOptions> {
    const tokens = labelToParse.split('\\ ');
    if (tokens.length !== 2) {
        throw new Error('Semester label has incorrect number of tokens');
    }
    const label = tokens[0];
    const year = parseInt(tokens[1], 10);
    if (year < OFFSET) {
        throw new Error('Year cannot be earlier than ' + OFFSET);
    }
    const nameIndex = NAMES.indexOf(label);
    if (nameIndex === -1) {
        throw new Error(`Name of the semester must be one of ${NAMES.join(', ')}`);
    }
    const semesterNumber = (year - OFFSET) * 3 + nameIndex;
    return {
        semesterNumber,
        label
    }
}

Для getOrDefault: используйте get и проверьте, является ли результат undefined (или ложный). На falsy есть ярлык с тестом:

const val = myMap.get(myKey) || myDefautValue;

… но в вашем случае более уместно утверждение if.

Для putIfAbsent: сначала используйте has, чтобы проверить, существует ли уже ключ, затем при необходимости используйте set.

Другие вопросы по теме