TypeScript在打破固定原则时不会抛出错误

zpgglvta  于 2023-10-22  发布在  TypeScript
关注(0)|答案(2)|浏览(116)

在Java中,当我们尝试执行以下情况(多态性)时,它会给我们一个编译错误/异常,这是预期的。但在打印稿中它不会给予我们错误。为什麽?
虽然我们不是在扩展一个类,或者更确切地说,一个接口,并且我们在一个发送对象数组的循环中调用以下面的方式实现的方法,但它通常会给出一个编译错误(在Java中)。但是在typescript中,为什么它不仅允许编译,而且即使对象不属于类/接口,它也会运行执行方法。这种按类/接口过滤的过程在我们将SOLID原则应用于所有接口的情况下非常有用。为什么这会发生在打字机上?这是违反原则的。

class Developer {
    drink() {
        console.log(" drink coffee ");
    }
}
class Musician {
    drink() {
        console.log(" drink beer ");
    }
}
class Vintage extends Developer {
    drink() {
        console.log(" drink tea ");
    }
}

class Vegan {
    drink() {
        console.log(" drink water, ??????"); 
    }
}
function queue(processes: Array<Developer & Musician>) {
    processes.forEach(p=>p.drink());
}

let p = [
    new Developer(),
    new Musician(),
    new Vintage(),
    new Vegan(), // Why is this happening?. this does not comply with SOLID.
    new Vegan() // Why is this happening?. this does not comply with SOLID.
]
queue(p);

TypeScript don't throw an error
我一直在Java中测试,但是...你可以看到 typescript 没有正确地抛出错误,我的意思是误报。我做错了什么?

bhmjp9jg

bhmjp9jg1#

不,你没有错。这里的问题是,TypeScript识别的是by-structure而不是by-inheritance。这就是所谓的“结构类型”。

ijxebb2r

ijxebb2r2#

正如@user-id-14900042所说的,类型脚本是structural typing,而你只调用了类的drink方法。对于TypeScript来说,drink函数的存在很重要,这样你的代码就不会出错。如果你改变饮料方法的名称,它会抛出一个错误:

正式文件

TypeScript是一种结构化类型系统。结构类型系统意味着在比较类型时,TypeScript只考虑类型上的成员。这与名义类型系统相反,在名义类型系统中,您可以创建两个类型,但不能将它们相互赋值。
容易出现错误代码:

class Vegan {
    sayHello() {
        console.log("HelloWorld!"); 
    }
}
function queue(processes: Array<Developer & Musician>) {
    processes.forEach(p=>p.drink()); // throw an error...
}

相关问题