区分空对象类型和其他具体类型

时间:2015-01-24 05:54:25

标签: typescript

所有这些编译都没有错误:

interface Empty { }
interface MaybeEmpty { a?: number; }

var one: Object = 20;
var two: Empty = 21;
var three: {} = 22;
var four: MaybeEmpty = 23;

有没有办法定义一个包含所有可选属性的类型,但是它仍然区别于stringnumberboolean等非对象类型?

2 个答案:

答案 0 :(得分:4)

没有

根本问题是,当在需要对象的上下文中使用时,JavaScript经常将原始值视为它们的对象类型等价物(String / Number / etc)(例如属性)访问)。

TypeScript使用"外观类型" 对此进行建模,其中基本类型的对象似乎具有相应对象类型的成员。这是因为,直观地说,像这样的代码应编译而不会出错:

function fn(x: { toString(): string }) { /* ... */ }
fn(32); // Should be OK because (32).toString() is OK
fn('foo'); // Should be OK because ('foo').toString() is OK

这段代码的一小步:

function fn(x: { toString(): string; other?: whatever; }) { /* ... */ }
fn(32); // Should be OK
fn('foo'); // Should be OK

这段代码又迈出了一小步:

function fn(x: { other?: whatever; }) { /* ... */ }
fn(32); // OK, I guess?
fn('foo'); // OK, I guess?

issue on GitHub跟踪一般问题,即在将分配给时,具有所有可选属性的接口实际上永远不会成为错误的来源。这对规格来说非常困难。

答案 1 :(得分:0)

Necromancing。
有这个问题我自己。
这在TypeScript 2.2+中实际上是可行的。

您需要添加&对象到您的类型定义

e.g。

var varname: YourInterface & object = something;

在你的情况下:

interface Empty { }
interface MaybeEmpty { a?: number; }
interface MaybeEmptyAndMore { a?: number; [x:string]: any; }


var one: Object = 20;
var two: Empty = 21;
var three: {} = 22;
var four: MaybeEmpty & object = 23;
var foura: MaybeEmpty & object = {};
var fourb: MaybeEmpty & object = { a: "23"};
var fourc: MaybeEmpty & object = { abc: "23"};
var fourd: MaybeEmptyAndMore & object = { abc: "123", def: "456" };

顺便说一句,如果它可以是字符串或接口(对象),那么:

obj: string | YourInterface & object

e.g。

class Cookie
{
    constructor(nameOrSettings: string | ICookieSettings  & object )
    {
        if(typeof(nameOrSettings)  === 'string')
        { do_something();}
        else if(typeof(nameOrSettings) === 'object')
        {
             var obj:ICookieSettings = <ICookieSettings><any>nameOrSettings;
        }
        else throw TypeError("foo");
    }
}