Skip to content

Suggestion: implement "implements" operator #15174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
fis-cz opened this issue Apr 13, 2017 · 9 comments
Closed

Suggestion: implement "implements" operator #15174

fis-cz opened this issue Apr 13, 2017 · 9 comments
Labels
Duplicate An existing issue was already created

Comments

@fis-cz
Copy link

fis-cz commented Apr 13, 2017

Hello,

I would like to ask if it would be possible to implement the "implements" operator for run-time returning true or false based on evaluation if object implements an interface.

I can imagine there will be a lot of edge cases but for simple class - implements statements it would be simply doable.

Lets take a look on the following example:

interface ICredentials {
   username: string;
   password: string;
}

class A implements ICredentials {
   username: string;
   password: string;
   ...
}

class B {
   ...
}

let a: A = new A();
let b: B = new B();

# true
console.log(A implements ICredentials);
console.log(a implements ICredentials);

# false
console.log(B implements ICredentials);
console.log(b implements ICredentials);

for such cases we need to write something like:

   function implementsICredentials(obj: any): boolean {
      return
         obj.hasOwnProperty("username") &&
         obj.hasOwnProperty("password");
   }

It is quiet a lot of code to be written manually if we want to test multiple interfaces. I can imagine the compiler could generate such functions for us.

Thanks for response.
Regards,
Franta

@RyanCavanaugh
Copy link
Member

Duplicate #5896, #1549, etc.

You might want to try https://www.npmjs.com/package/dtsgenerator or similar tools

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Apr 13, 2017
@fis-cz
Copy link
Author

fis-cz commented Apr 13, 2017

Yep, but... you know... implements would be nicer. I get you don't want to add so much additional code.

@ghost
Copy link

ghost commented Apr 13, 2017

This also just isn't doable.

interface I {
	m(x: number): number;
}

function f(x: {}): x is I {
	...
}

There's no way we can fill in the body of that function for you automatically.
Suppose we try typeof f.m(0) === "number".
If it does return a number: how do we know it always does?
If it throws an exception: How do we know it isn't just a problem with the number 0?

Also, we would be doing an arbitrary amount of work.

@fis-cz
Copy link
Author

fis-cz commented Apr 13, 2017

I am sorry, but i don't understand what you mean by this.

Where do you say that x implements something?

in my case, i just wanted to know if members defined by the interface exists on the object.

@ghost
Copy link

ghost commented Apr 13, 2017

Just because an object has all the same keys doesn't mean that it actually implements the interface.

@fis-cz
Copy link
Author

fis-cz commented Apr 13, 2017

Thats true :) But there is no another option, how to check it right? If we will not take reflection into account.

@ghost
Copy link

ghost commented Apr 13, 2017

Why would you want that, though? If you don't trust an object, no amount of checking will suffice. If you do trust an object, you should give it an O(1) way of identifying itself as a member of the interface, as in:

interface Foo {
    __fooBrand: true;
}

class C implements Foo {
    get __fooBrand(): true { return true; }
}

function isFoo(obj: {}): obj is Foo {
    return !!(obj as Foo).__fooBrand;
}

@fis-cz
Copy link
Author

fis-cz commented Apr 13, 2017

Its complicated. I am using it together with generics so I am good at compile time but I wanted to make sure the same at runtime.

Nice workaround, thanks for recommendation! I'll try to implement it like that.

@fis-cz fis-cz closed this as completed Apr 13, 2017
@aluanhaddad
Copy link
Contributor

aluanhaddad commented Apr 14, 2017

@novakf
I really think @Andy-MS cuts right to the heart of the matter when he asks

Why would you want that, though? If you don't trust an object, no amount of checking will suffice. If you do trust an object, you should give it an O(1) way of identifying itself as a member of the interface, as in:

This is so true that even cases like

class Credentials) { }

class A extends Credentials { } // prototype chain will preserve basic heritage.

const a = new A();

console.log(a instanceof Credentials); // true

It does guarantee any runtime argument validation, let alone security, at all.

class Credentials { }

class A extends Credentials { } // prototype chain will preserve basic heritage.

const credentials = {
  __proto__: Credentials.prototype
};

console.log(credentials instanceof Credentials); // true

@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants