从java转换后如何修复typescript类文件错误?

Posted

技术标签:

【中文标题】从java转换后如何修复typescript类文件错误?【英文标题】:How to fix typescript class file error after converting from java? 【发布时间】:2019-08-31 01:48:51 【问题描述】:

我有一个 Java 类,我想在 typescript 项目中使用该类。但我试图转换它并从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。我不明白应该在这里写什么。

你能帮我修复这个打字稿代码吗? 提前致谢。

【问题讨论】:

【参考方案1】:

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

一些建议:

选择undefinednull,但不要同时使用这两种方法。在下面的示例中,我使用undefined; 在模块中,静态成员可以替换为简单的变量; 首选interface,而不是多个可选参数; 你的 IIFE ((() =&gt; … ();) 没用; 当推理足够时不要声明类型; 首选原始类型(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

【讨论】:

【参考方案2】:

关于构造函数

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

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

检查“传入的内容”的方法不需要在一个 if 语句中进行太多检查。在这里查看以下答案:https://***.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 或未定义或为空,如果是这种情况,请执行 new Semester(...)。

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

【讨论】:

以上是关于从java转换后如何修复typescript类文件错误?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript之间转换

typescript eventTarget dataset 如何修复报错?

从 JavaScript 到 TypeScript - 接口

如何在 IntelliJ IDEA 中修复“不支持的类文件主要版本 60”?

如何修复'Typescript“正在进行类型检查......”花费太长时间'?

如何将 Javascript 文件导入 Typescript