2015-01-24 1 views
4

Всем это компилируется без ошибок:различия между пустым типом объекта и другими конкретными типами

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

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

Есть ли способ определить тип со всеми дополнительными свойствами, но тем не менее дискриминирует тип необъектных как string , number и boolean?

ответ

3

No.

Корень проблемы в том, что JavaScript часто рассматривает примитивные значения, как если бы они были их объектов типизированных эквиваленты (String/Number/и т.д.) при использовании в условиях, когда требуется объект (например, доступ к свойству).

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 отслеживание общей проблемы, что интерфейс со всеми необязательными свойствами фактически никогда не является источником ошибки при присвоении -. Это очень сложно.

+0

Нет неверных данных - возможно сейчас. – User1

1

Некроментарий.
Если бы эта проблема была сама.
Это действительно возможно в TypeScript 2.2+.

Вам нужно добавить & объект вашего типа четкостью

например

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 

например,

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"); 
    } 
} 
Смежные вопросы