从Java转换后如何解决Typescript类文件错误?

时间:2019-04-09 17:40:15

标签: java typescript

我有一个Java类,我想在打字稿项目中使用哪个类。但我尝试将其转换,也从http://www.jsweet.org/jsweet-live-sandbox/那里获得了帮助。我的打字稿非常新,我是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中的多个构造函数编写的正确方法。 其次,在打字稿中我没有在Map中找到getOrDefault,putIfAbsent。我不明白该写些什么。

您能帮我解决此打字稿代码吗? 预先感谢。

2 个答案:

答案 0 :(得分:1)

关于构造函数

您猜对了,没有像Java那样拥有多个构造函数(又称构造函数重载)。您在TypeScript中只有一个构造函数,并且需要有可选参数。

在您的情况下,semesterNumber和label可以是未定义的,也可以是数字/字符串,不需要类型检查。

一种检查“传入的内容”的方法,您不需要在一个if语句中进行太多检查。在这里查看以下答案:https://stackoverflow.com/a/44017547/8745384

关于地图

相当于“ putIfAbsent”的是一个简单的“ set(key,value)”

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

对于getOrDefault,您可以编写

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

它的作用与我之前对if语句描述的相同。检查是否为null或undefined或为空,如果是这种情况,请执行新的Semester(...)。

希望我能帮上忙。我最近也从Java切换到TypeScript,所以也许有一种更好的方法,然后我描述了。

答案 1 :(得分:1)

我也有Java背景,但是年龄较大。 ;-)

一些建议:

  • 选择undefinednull,但不要同时使用两者。在下面的示例中,我使用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)。在falsy上有一个测试快捷方式:

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

…但是对于您而言,if语句更合适。

对于putIfAbsent:首先使用has测试密钥是否已存在,然后在必要时使用set