为什么setter函数接受与typescript中的字段相同的数据类型?

为什么setter函数接受与typescript中的字段相同的数据类型?,typescript,Typescript,我试图使用setter函数将字符串值插入typescript类中的私有数组。 在我的getter函数中,intellisense表示返回的值是类型不匹配的,如下面的代码所述 export class Player{ constructor(private _skills:string[]){} get skills(){ return this._skills // Type string not assignable to type string[]

我试图使用setter函数将字符串值插入typescript类中的私有数组。 在我的getter函数中,intellisense表示返回的值是类型不匹配的,如下面的代码所述

export class Player{
    constructor(private _skills:string[]){}

    get skills(){
        return this._skills  // Type string not assignable to type string[]
    }

    set skills(newSkill:string){
        this._skills = [...this._skills,newSkill]
    }
}
在将显式函数参数type
newSkill:string
删除为just
newSkill
时,上述错误得到解决,因为typescript希望在setter中传递字符串数组,而不仅仅是字符串

我们可以插入单个字符串,方法是将其封装在数组中,然后将传递的数组与私有数组字段合并

player.skills = ["single skill"]
但是,对于一次只需要向技能数组而不是技能数组插入一个技能值的情况,我们为什么要向setter函数传递数组而不仅仅是字符串呢

为什么数组只有一个字符串而不仅仅是字符串(作为setter函数中的数据类型)是个问题

是否可以避免使用字符串数组数据类型并将其设置为字符串数据类型

注意:
要求是一次插入/设置一个字符串值,而不是使用Type Script的set关键字将值数组插入技能数组。要知道setter函数总是希望将字段类型的值传递给它

在本例中,skills是一个字符串数组。因此setter需要一个字符串数组作为参数

player=新玩家([“someskills”])
player.skills=[…somemoreskills]//必须是字符串[]而不是字符串
结论: setter参数datatype默认为field datatype,并且似乎不可避免地将其更改为只接受字符串,而不接受字符串数组。 作为使setter同时使用string和string[]的解决方法,我们可以使用pipe

解决方法:接受单个字符串,但也接受字符串数组。
建议将setter param数据类型单独设置为(
string
)会有所帮助

这与场地无关。
技能
\u技能
之间没有内在联系。要求是getter的返回类型必须与setter的参数类型匹配

您可以使用以下方法处理此问题:

但是你不应该,原因如下:

  • 每次使用getter都必须检查它是得到一个字符串还是一个字符串数组,即使它总是返回一个数组

  • 非对称API已经被证明是很难学习和使用的(想想
    document.cookie
    ,不寒而栗)。(上面的API实际上是不对称的,尽管它不在定义中,因为getter总是返回一个数组。)

  • 相反,如果希望技能成为数组,请将其设置为数组,并使用一种方法添加单个技能或技能数组:

    export class Player {
        constructor(private _skills: string[]) {
        }
    
        // Gets the array of skills -- you might want to make a
        // defensive copy, or return a frozen version or similar
        get skills() {
            return this._skills;
        }
    
        // Sets the array of skills, OVERWRITING previous ones
        set skills(newSkills: string[]) {
            this._skills = newSkills.slice();
        }
    
        // Adds one or more skills, which can be given as individual
        // strings or arrays of strings
        addSkills(...skills: (string|string[])[]) {
            // Add all the skills, which 
            this._skills.push(...skills.flat());
        }
    }
    

    (注意:这使用了新方法。)

    “要知道setter函数总是希望将字段类型的值传递给它。”这是错误的。我会发布一个答案。Making
    foo.skills=[“x”,“y”]添加技能而不是替换技能是一个骗局。感谢@T.J.提供了如此深刻的回答,正如你提到的,setter参数取决于getter的返回类型,而getter的返回类型又取决于字段类型,正如任何getter函数所期望的那样……对于这种情况,一个好的结论是,只能传递字符串是不可避免的数据类型作为ts setter的一个参数,最好是创建单独的setter函数来处理这两个函数,正如您所提到的。同意吗?@AdityaPatnaik-是的,如果你需要对所给的东西做任何“特别”的事情,我会把这部分作为一种方法而不是访问器。非常感谢@T.J.,我从你的回答中学到了很多。
    
    set skills(newSkill:string[]|string){
            if(typeof(newSkill)==='string'){
                this._skills = [...this._skills,newSkill]
            }else{
            this._skills = [...this._skills,...newSkill]
            }
        }
    
    export class Player {
        constructor(private _skills: string[]) {
        }
    
        get skills() {
            return this._skills;
        }
    
        set skills(newSkill: string[] | string) {
            if (typeof newSkill === "string") {
                this._skills.push(newSkill);
            } else {
                this._skills = newSkill.slice(); // Note: Completely replaces the value
            }
        }
    }
    
    export class Player {
        constructor(private _skills: string[]) {
        }
    
        // Gets the array of skills -- you might want to make a
        // defensive copy, or return a frozen version or similar
        get skills() {
            return this._skills;
        }
    
        // Sets the array of skills, OVERWRITING previous ones
        set skills(newSkills: string[]) {
            this._skills = newSkills.slice();
        }
    
        // Adds one or more skills, which can be given as individual
        // strings or arrays of strings
        addSkills(...skills: (string|string[])[]) {
            // Add all the skills, which 
            this._skills.push(...skills.flat());
        }
    }