所有这些编译都没有错误:
interface Empty { }
interface MaybeEmpty { a?: number; }
var one: Object = 20;
var two: Empty = 21;
var three: {} = 22;
var four: MaybeEmpty = 23;
有没有办法定义一个包含所有可选属性的类型,但是它仍然区别于string
,number
和boolean
等非对象类型?
答案 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");
}
}