2016-04-13 3 views
9

у меня есть модуль окружающей среды машинописи представляет собой библиотеку, которая поддерживает любые посылы/A + библиотека:Использования пользовательского перспективны в качестве универсального типа

interface Test { 
    funcName():Promise<string>; 
} 

Поэтому мне нужно настроить его таким образом, чтобы протокол любого посыла библиотеки, доступной на декларативном уровне:

interface Test<P> { 
    funcName():P<string>; 
} 

Но машинописи сразу жалуется: Type 'P' is not generic, прежде чем я даже использовать его.

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

И если я изменить код для этого:

interface AnyPromise<T, P extends Promise<T>> { 
} 

interface Test<P> { 
    funcName():AnyPromise<string, P<string>>; 
} 

Он также сетует error TS2315: Type 'P' is not generic. в этой части: P<string>.

В конце концов, мне нужно, чтобы быть в состоянии сделать что-то вроде этого:

import * as promise from 'bluebird'; // from Bluebird ambient declarations 
import {Test} from 'test'; 

var Test<promise> t; // plus initialize it; 

t.funcName().finally(())=>{ 
}); // NOTE: 'finally' is to be visible from Bluebird (doesn't exist in ES6 Promise) 

Чтобы раз уточнить, я использую Bluebird только в качестве примера, как мне нужно решение поддержать любую библиотеку обещание, а не один конкретный.

+0

Почему 'Test ', разве это не должно быть 'Test '? – Bergi

+0

@Bergi, который сообщает компилятору относиться к переменной как к классу. Но это не имеет значения, потому что ошибка возникает перед этим вызовом, при анализе класса 'Test'. Я обновил вопрос;) –

+0

Вам нужно определить структурный интерфейс 'then'able, хотя я думаю, что bluebird будет структурно передаваться как обещание ES2015, поскольку он имеет точно такие же сигнатуры функций. –

ответ

5

Для использования в TypeScript требуется более высокий тип сорта. Вопрос, который отслеживает их здесь:

https://github.com/Microsoft/TypeScript/issues/1213

По состоянию на апрель 2016 года, его пока не представляется возможным.

Вы можете аппроксимировать некоторые из них с типами продукции, но она нуждается в модификации PromiseLike типа, и вам нужно будет явно передать параметр типа вокруг любой момент вы используете then в вашей библиотеке:

interface HKPromiseLike<T> { 
    then<TResult, P>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): P & HKPromiseLike<TResult>; 
    then<TResult, P>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): P & HKPromiseLike<TResult>; 
} 

class Wrapper<T, P> { 
    constructor(public p:P & HKPromiseLike<T>) {} 

    map<U>(f:(t:T) => U) { 
     var res = this.p.then<U, P>(f) 
     var w = new Wrapper(res); 
     return w 
    } 
} 

Чтобы специализировать эту оболочку, вы должны использовать класс/extends.

class Specialized<T> extends Wrapper<T, SomePromise<T>> { } 
+0

Пройдя через эту функцию, вы увидите, что она выглядит довольно тусклой. –

+0

Меня попросили реализовать эту функцию, но я терпел неудачу снова и снова. Просто не решался сказать «НЕТ», это невозможно, из-за моего отсутствия знаний о TypeScript. Теперь я уверен, что это действительно невозможно, и то, что я делаю это в своей библиотеке, - единственный (хотя и уродливый) способ сделать это - вручную исправление с пользовательским обещанием: https: // github. ком/виталий-т/пг-обещание/BLOB/Master/машинопись/promise.ts. Спасибо за пояснение! –

+0

Я рекомендую прокомментировать проблему с TypeScript и добавить туда свою проблему. Он покажет команде TS, что функции полезны, а не только для кода стиля FP ... –

Смежные вопросы