问题
With TypeScript 1.6 is it possible to write functions to check objects against interfaces. (Below is the anncouncement from MSDN and how to use it.)
My question targets the return expression return a.name === 'kitty';
:
- Plays it an role?
- Must all cats called kitty?
User defined type guards
[http://blogs.msdn.com/b/typescript/archive/2015/09/16/announcing-typescript-1-6.aspx]
In earlier versions of TypeScript, you could use if statements to narrow the type. For example, you could use:
if (typeof x === "number") { … }
This helped type information flow into common ways of working with types at runtime (inspired by some of the other projects doing typechecking of JS). While this approach is powerful, we wanted to push it a bit further. In 1.6, you can now create your own type guard functions:
interface Animal {name: string; } interface Cat extends Animal { meow(); } function isCat(a: Animal): a is Cat { return a.name === 'kitty'; } var x: Animal; if(isCat(x)) { x.meow(); // OK, x is Cat in this block }
This allows you to work with not only typeof and instanceof checks, which need a type that JavaScript understands, but now you can work with interfaces and do custom analysis. Guard functions are denoted by their “a is X” return type, which returns boolean and signals to the compiler if what the expected type now is.
回答1:
Consider your example
interface Animal {name: string; } - an interface
interface Cat extends Animal { - an implementation
meow();
}
function isCat(a: Animal): a is Cat {
return a.name === 'kitty'; // your special checking you can replace it with any other checking expression
}
var x: Animal;
if(isCat(x)) {
x.meow(); // OK, x is Cat in this block
}
This example show, that now, we can use expression like a is Cat
and in the follow block, where checking has been already used, type of a
would be Cat
. The return a.name === 'kitty';
expression you can replace with
function isCat(a: Animal): a is Cat {
return a["meow"] != undefined; // it also would be indicate that the animal is Cat
}
and it would be work.
Even you can replace it with this too
function isCat(a: Animal): a is Cat {
return true;
}
I have prepared example for you, you can play with it.
Conclusions:
- Expression
a is Cat
provide same effect asa instanceof SomeClass
, but first one is customizable checking instead of last one, and last one does not work with interfaces. - Your checking function can contain any code - it is your choice
- This future give us possibility to check if instance is inctanceof interface
Update
- Plays it an role?
- Yes, it plays.
a.name === 'kitty'
- this expression show the logic of checking that given animal IS -Cat
, so, here you can provide anyboolean
expression that check that given animal isCat
even you can return justtrue
orfalse
;
- Yes, it plays.
- Must all cats called kitty?
- No. It is up to you. In function
isCat
you can provide any logic that ensure that given animal is of typeCat
- No. It is up to you. In function
回答2:
Your questions regarding return a.name === 'kitty';
:
1)Does it plays a role?
Yes, the return value determines whether the type guard passes or fails.
2)Must all cats called kitty?
Yes, in this case, all cats must be called Kitty.
What it comes down to, it this was not a very good example.
A better one would be...
class Animal {name: string; type: string; }
class Cat extends Animal {
type: string = "Cat";
meow() {};
}
function isCat(a: Animal): a is Cat {
return a.type === 'Cat'; // your special checking you can replace it with any other checking expression
}
var x: Animal = new Cat();
if(isCat(x)) {
x.meow(); // OK, x is Cat in this block
}
see JSFiddle.
来源:https://stackoverflow.com/questions/32713452/user-defined-type-guards-typescript