2016-10-25 2 views
1

Я переношу проект JavaScript в TypeScript.
Использование модуля узла в TS, такие как URL вызывают некоторые проблемы для меня:Избежать Тип '{}' не может быть присвоен типу 'X'

import nodeUrl = require('url'); 
// ... 
// this worked fine in JS 
nodeUrl.format({ 
    // just for demonstration 
    x: this.getX(someObj), 
    y: this.getY(someObj) 
}); 

Результатов в:

типа '{}' не присваиваемый типа 'строки'

Это связано с определением этой функции модуля. От @ типов/узла/index.d.ts:

declare module "url" { 
    export interface Url { 
     href?: string; 
     protocol?: string; 
     auth?: string; 
     hostname?: string; 
     port?: string; 
     host?: string; 
     pathname?: string; 
     search?: string; 
     query?: string | any; 
     slashes?: boolean; 
     hash?: string; 
     path?: string; 
    } 

    export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; 
    export function format(url: Url): string; 
    export function resolve(from: string, to: string): string; 
} 

Мой вопрос, как избежать/исправить эту ошибку без изменения файла декларации?

+0

Что вы пытаетесь сделать, чтобы это так 'format' будет принимать произвольные ключи? Я могу ответить на это. –

+0

Я хочу, чтобы компилятор проигнорировал тот факт, что я передаю объект JSON методу 'format', который ожидает объект' Url'. Или способ * конвертировать * мой JSON в объект 'Url' (зависит от того, какой подход чище/проще). – lenny

ответ

1

Должно быть что-то вроде:

import nodeUrl = require('url'); 

declare module "url" { 
    export function format(url: Url): string; 
    export function format(x: any, y: any): string; 
    export function format(url: any): string; 
} 

Более подробную информацию об этом можно найти в Module Augmentation.

+0

Итак, если я правильно понял, это «переопределит» существующее заявление? – lenny

+0

Вы не должны переопределять его, но дополнять его. Вы хотите сохранить существующее определение, но добавить к нему –

0

Вы можете использовать индексную подпись:

export function format(url: {[index: string]: string}): string 

Это сделает это так, чтобы format все еще требует объекта со строковыми ключами и значениями, но ключевые имена могут быть все что угодно. Конечно, вы можете смешивать и сопоставлять типы в соответствии с вашими потребностями.

0

нашел другой способ, чтобы исправить это:

nodeUrl.format(<any> { 
    // just for demonstration 
    x: this.getX(someObj), 
    y: this.getY(someObj) 
}); 
+0

Но тогда вы потеряете тип безопасности –

+0

Я бы тоже с вашим подходом, так или иначе, в моем случае я могу его принять. – lenny

+0

Мой подход говорит, что вы добавляете подписи, которые соответствуют определенным типам (это также должно соответствовать фактической реализации, конечно). Вам следует избегать использования 'any', я просто использовал его, чтобы показать, что вы можете добавлять подписи. –

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