如何确保传递给函数的参数是打字稿中类的实例?

时间:2019-05-19 14:54:42

标签: typescript

我有两个班,:help function-range-exampleDatabase。我有一个函数,它接受数据库类实例作为参数。如何确保该函数仅接受数据库类实例,而不接受其他任何实例。

我知道我可以使用DatabaseEnc来检查实例是否属于checkConn函数中的数据库。但是我正在寻找一种基于打字稿的解决方案。

instance of

除了数据库以外,我不能将其他任何实例传递给/* database.ts */ class Database { public state: string = null; constructor(state: string) { this.state = "some state"; } } export default Database; /* database_enc.ts */ class DatabaseEnc { public state: string = null; constructor() { this.state = "some other state"; } } export default DatabaseEnc; /* provider.ts */ import Database from "./database"; import DatabaseEnc from "./database_enc"; function checkConn(db: Database): void { Log.print(db); } // wrong, I should not be allowed to pass DatabaseEnc // instance to the checkConn function parameter const test = new DatabaseEnc(); checkConn(test); // right, checkConn function should only accept Database // class instance as a parameter const test1 = new Database(); checkConn(test1); // what is happening? I am allowed to pass any class's instance // to the checkConn function. 函数。

1 个答案:

答案 0 :(得分:1)

TypeScript在结构上是类型化的,这意味着如果两个类型具有相同的结构,则将它们视为相同。请参阅TS文档中的Type Compatibility部分。这是一个方便的行为,并且从JS的角度来看是正确的,因为这两个对象都将在运行时具有相同的属性。

话虽这么说,当这两个类分开时,您将开始遇到类型错误(例如,通过向Database类添加新属性),因此您仍然会得到某种类型的控件以后。

我认为您不应该尝试破解这种行为并接受它,因为这是与("program to interfaces, not implementations")一起使用的好原则。您应该期望对象具有特定的能力,而不是期望某些特定的类。

interface Checkable {
  checkConnection: (param: string) => boolean
}

class Database implements Checkable {
    // ...
    checkConnection(param: string) {
        return true
    }
}

// Is not Checkable.
class DatabaseEnc {
    // ...
}

// Allow all objects that can be checked.
function checkConn(db: Checkable): void {
    Log.print(db.check());
}

const test = new DatabaseEnc();
checkConn(test); // OK

const test1 = new Database();
checkConn(test1); // Error, since it doesn't implements the Checkable interface.