2015-05-18 4 views
0

У меня есть функция wrap, которая может принимать либо T, либо Wrapped<T> и возвращает Wrapped<T>.TypeScript 1.4: Использование разъемов типа

Заявленный в TS 1.0:

wrap<T>(value: Wrapped<T>, defaultValue?: T): Wrapped<T>; 
wrap<T>(value: T, defaultValue?: T): Wrapped<T>; 

Теперь в 1.4, я хочу использовать типы профсоюзов, чтобы определить понятие "либо T или Wrapped<T>"

class Bar { 
    thing: Wrapped<number>; 
    constructor(thing: number | Wrapped<number>) { 
     this.thing = wrap(thing); 
    } 
} 

Но тип проверки ошибки на this.thing определение:

Тип Обернутый < номер | Упакованный < номер >> не подлежит обертыванию < номер>

Тип 'номер | Облаченный < число>»не может быть назначен набрать номер

Я понимаю, что ошибка в том, что значение я передаю к wrap является number | Wrapped<number> и wrap только знает, как обращаться с number и Wrapped<number>;

Итак, моя первая попытка состояла в том, чтобы объявить, что она может обрабатывать T | Wrapped<T>;

wrap<T>(value: T | Wrapped<T>, defaultValue?: T): Wrapped<T>; 
wrap<T>(value: Wrapped<T>, defaultValue?: T): Wrapped<T>; 
wrap<T>(value: T, defaultValue?: T): Wrapped<T>; 

Но тип проверки все еще ошибки. Если я щелкнул правой кнопкой мыши и перешел к определению, я вижу, что он по-прежнему привязан к третьему определению в списке, а не к моей более ранней сигнатуре с более высоким приоритетом для T | Wrapped<T>.

Является ли это ожидаемым поведением?

Должен ли я решить это руководство с помощью типоразмеров? Если да, может ли кто-нибудь показать мне, как это сделать с этим общим Обертоном, который у меня есть? Как получить параметр типа из моей переменной thing?

ответ

1

компилируется:

interface Wrapped<T> { value: T } 
declare function wrap<T>(value: T|Wrapped<T>, defaultValue?: T): Wrapped<T>; 

class Bar { 
    thing: Wrapped<number>; 
    constructor(thing: number | Wrapped<number>) { 
     this.thing = wrap(thing); // No error 
    } 
} 

Общие рекомендации по выбору между типом союза и функции двух перегрузках в том, что если вы можете записать его как тип союза одной подписи, вы должны.

+0

Так что ответ: удалить старые подписи и позволяют новую подпись, чтобы сделать работу обоих. Круто. Я надеялся на что-то простое. Еще раз спасибо Райан! (Вы быстро на ничью). – masonk

1

Просто объединить перегруженные функции:

class Wrapped<T> { 

    private _value: T; 
    get value(): T { return this._value; } 

    constructor(value: T) { 
     this._value = value; 
    } 
} 

class WrappHelper { 

    public static wrap<T>(value: Wrapped<T> | T, defaultValue ?: T): Wrapped<T> { 
     if (value instanceof Wrapped) 
      return value; 
     else 
      return new Wrapped<T>(<T>value); 
    } 
} 

var a = new Wrapped(100); 
var b = 200; 

var a1: Wrapped<number> = WrappHelper.wrap(a); 
var a2: Wrapped<number> = WrappHelper.wrap(b);