Javascript 如何在TypeScript(.Net等效)中创建TryCast

Javascript 如何在TypeScript(.Net等效)中创建TryCast,javascript,typescript,typescript1.5,Javascript,Typescript,Typescript1.5,我很惊讶我们没有看到太多关于在电影中扮演角色的东西。尝试在TypeScript中创建一个简单的tryCast函数,类似于.Net中的函数。因此,基本上,尝试转换为指定的类型,如果失败,则返回null/nothing。也许它应该使用类型脚本 这就是你要找的吗 interface IFoo { bar: any; } function tryCast(obj: number, type: "number"): number; function tryCast(obj: string, type:

我很惊讶我们没有看到太多关于在电影中扮演角色的东西。尝试在TypeScript中创建一个简单的tryCast函数,类似于.Net中的函数。因此,基本上,尝试转换为指定的类型,如果失败,则返回null/nothing。也许它应该使用类型脚本
这就是你要找的吗

interface IFoo { bar: any; }

function tryCast(obj: number, type: "number"): number;
function tryCast(obj: string, type: "string"): string;
function tryCast(obj: boolean, type: "boolean"): boolean;
function tryCast(obj: IFoo, type: "IFoo"): IFoo;
function tryCast(obj: any, type: string): any;
function tryCast(obj: any, type: string): any {

    // Do fancy stuff to cast things
}

// IFoo
tryCast({ bar: 'hi' }, 'IFoo');

// any (NULL)
tryCast({}, 'string');

// boolean
tryCast( !!1 , 'boolean');

// any (NULL)
tryCast(123, 'boolean');

// number
tryCast(123, 'number');

// string
tryCast( 123 + '', 'string');

这是一个有趣的问题。我想不出一个好的场景,这种情况经常发生,足以保证一个通用函数。大多数时候,我都会逐案处理。对于原语和用户定义的类型,通常使用
typeof
。不过,这是一个很好的练习,所以我要试一试

您的代码正在执行
typeof
检查,但随后它会将变量冗余地传递给构造函数。如果
typeof obj===“number”
那么您已经有了一个数字,无需“强制转换”。以下是上文@mallison给出的答案的修改版本。我还为此解决方案添加了一个类,但是接口并不像您希望的那样工作

// Overloaded function
function tryCast(o: number, t: "number"): number;
function tryCast(o: string, t: "string"): string;
function tryCast(o: boolean, t: "boolean"): boolean;
function tryCast(o: IFace, t: "IFace"): IFace;
function tryCast(o: Function, t: "function"): Function;
function tryCast<T>(o: any, t: string): T;
function tryCast<T>(o: T, t: any): T {
     if (t === typeof o || (o['constructor'] && t === o['constructor']['name'])) {
        return o;
     } else  {
        return null;
     }
}

// Usage examples
var s1 = tryCast(70, 'string');
var s2 = tryCast('hello world', 'string');
var b1 = tryCast({b:true}, 'boolean');
var b2 = tryCast(true, 'boolean');
var n1 = tryCast('nan', 'number');
var n2 = tryCast(91, 'number');

var f1 = tryCast(123, 'function');
var f2 = tryCast(function foo() { return 1}, 'function');

class Classy { public sanDeigo = true; }
var c1 = tryCast<Classy>({soFly:false}, 'Classy');
var c2 = tryCast<Classy>(new Classy(), 'Classy');

interface IFace { eyes: number; hasMouth: boolean; }
var i1 = tryCast<IFace>({ eyes: 2, fake: true }, 'IFace');
var i2 = tryCast<IFace>({ eyes: 2, hasMouth: true }, 'IFace');

// Runtime tests
document.write(`
    s1:${s1},   // expect null<br/>
    s2:${s2},   // expect string<br/>
    b1:${b1},   // expect null<br/>
    b2:${b2},   // expect boolean<br/>
    n1:${n1},   // expect null<br/>
    n2:${n2},   // expect number<br/>
    f1:${f1},   // expect null<br/>
    f2:${f2},   // expect function<br/>
    c1:${c1},   // expect null<br/>
    c2:${c2},   // expect Classy<br/>
    i1:${i1},   // expect null<br/>
    i2:${i2},   // expect IFace...but its not!<br/>
`);

// Compiler tests
s1.toUpperCase();
s2.toUpperCase();

b1.valueOf();
b2.valueOf();

n1.toFixed(2);
n2.toFixed(2);

f1.apply(this);
f2.apply(this);

c1.sanDeigo;
c2.sanDeigo;

i1.eyes;
i2.eyes;
发生了什么事?因为接口是编译时实体,所以没有通用的方法强制转换接口。运行时不知道接口。该类可以工作,因为我们知道TypeScript将如何编译代码,但如果构造函数名称与类名不相同,这在将来可能不起作用(您可能希望在生产中使用它之前检查ES6规范)

同样,在运行时检查接口类型的唯一方法是duck类型,正如我前面提到的。对于编译时不知道类型的场景,我将给您留下我认为合适的解决方案

$.getJSON('data.json', function(data: IFace) {
    if (data && data.eyes > 0 && data.hasMouth) {
        // this looks like an IFace to me!
    } else {
        // data is no good!
    }
});

这怎么可能是typescript 1.4和typescript 1.5?选择一个标签。@royhowie好,全部完成。
s1:null, // expect null
s2:hello world, // expect string
b1:null, // expect null
b2:true, // expect boolean
n1:null, // expect null
n2:91, // expect number
f1:null,    // expect null
f2:function foo() { return 1; },    // expect function
c1:null,    // expect null
c2:[object Object], // expect Classy
i1:null,    // expect null
i2:null,    // expect IFace...but its not!
$.getJSON('data.json', function(data: IFace) {
    if (data && data.eyes > 0 && data.hasMouth) {
        // this looks like an IFace to me!
    } else {
        // data is no good!
    }
});