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

Typescript 区分空对象类型和其他具体类型,typescript,Typescript,所有这些编译都不会出错: interface Empty { } interface MaybeEmpty { a?: number; } var one: Object = 20; var two: Empty = 21; var three: {} = 22; var four: MaybeEmpty = 23; function fn(x: { toString(): string }) { /* ... */ } fn(32); // Should be OK because (32

所有这些编译都不会出错:

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

var one: Object = 20;
var two: Empty = 21;
var three: {} = 22;
var four: MaybeEmpty = 23;
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

是否有一种方法可以定义一个具有所有可选属性的类型,但它仍然可以区分非对象类型,如
字符串
数字
,和
布尔值

TS2.4+的更新,如果没有重叠的属性,现在有一个属性将阻止分配给所有可选属性类型,如
MaybeEmpty
,因此现在不允许
var four:MaybeEmpty=23


更新为TS2.2+,现在有一种类型专门排除原语。使用大括号的类对象类型,如
{}
{a?:number}
仍然与原语兼容,如下所述


原始答复:

没有

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

TypeScript使用“表观类型”对此进行建模,其中基元类型的对象似乎具有其相应对象类型的成员。这是因为,从直觉上看,这样的代码应该编译无误:

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

var one: Object = 20;
var two: Empty = 21;
var three: {} = 22;
var four: MaybeEmpty = 23;
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?
这段代码的另一小步:

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?
一个普遍的问题是,当分配给一个具有所有可选属性的接口时,它实际上永远不会是错误的来源。这是一件很难描述的事情。

亡灵巫术。
我自己也有这个问题
这在TypeScript 2.2+中实际上是可能的

您需要将&object添加到类型定义中

e、 g

就你而言:

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" };
顺便说一下,如果它可以是字符串或接口(对象),那么:

e、 g

类Cookie
{
构造函数(名称设置:字符串| ICookieSettings&对象)
{
if(typeof(nameOrSettings)==“string”)
{做某事();}
else if(typeof(nameOrSettings)==“object”)
{
var obj:ICookieSettings=名称设置;
}
否则抛出类型错误(“foo”);
}
}

更新了
对象
和弱类型检测的答案,希望您同意。