2014-12-09 2 views
0

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

Упрощенный пример с одного объекта:

// Auto-generated 

interface Report { 
    id: number; 
    title: string; 
} 

interface ReportEntityType extends EntityType<Report> { 
    properties: { 
     id: Property<number>; 
     title: Property<string>; 
    } 
} 

var entityTypes = { 
    Report: <ReportEntityType>{ 
     properties: { 
      id: { 
       dataType: "number" 
      }, 
      title: { 
       dataType: "string", 
       required: true, 
       displayName: "Title" 
      } 
     } 
    } 
}; 

Для полноты здесь являются ссылочные интерфейсы (также упрощены):

interface EntityType<T> { 
    properties: any; 
} 

interface Property<T> { 
    dataType: string; 
    required?: boolean; 
    displayName?: string; 
} 

хотя из проекта, интерфейс Report используется во время компиляции для тип проверки и intellisense, а объект метаданных entityTypes.Report используется как для компиляции, так и для времени выполнения для различных целей. Например, displayName используется для визуализации метки для свойства, а для проверки используется required.

Как я могу получить TypeScript для вывода типа Report с типом ReportEntityType?

Пример:

class Validator<TEntityType> { 
    constructor(entityType: EntityType<TEntityType>) { } 

    validate(obj: TEntityType) { } 
} 

var validator = new Validator(entityTypes.Report); 

В настоящее время, машинопись будет сделать вывод, что validator является Validator<{}>, но я хочу сделать вывод, что это Validator<Report>.

На основе замечаний машинописи команды here и here, проблема в том, что мой интерфейс EntityType<T> не использует сам параметр T:

Я думаю неизрасходованные параметры общего типа в целом, ошибка

не определить общие типы, которые не используют тип параметра типа

Справедливо. Интересно, что все, что мне нужно сделать, это добавить dummy?: T; к EntityType<T>, и он работает. Я хочу избежать этого взлома, и вместо этого реализовать это в идиоматическом стиле TypeScript. Как я должен это делать?

ответ

0

Упрощенный пример:

interface Report{} 
interface EntityType<T> { 
    properties: any; // Change to T and it works 
} 
interface ReportEntity extends EntityType<Report>{} 

var rep1:EntityType<Report>; 
var rep2:ReportEntity; 

class Validator<TEntityType> { 
    constructor(entityType: EntityType<TEntityType>) { } 
} 

var val1 = new Validator(rep1); // okay 
var val2 = new Validator(rep2); // Not okay 

Проблема здесь в том, что в отсутствие вы используете T в EntityType, rep2 эффективно EntityType<{}>. Поэтому нет хорошего решения, кроме как использовать T || не используйте расширенный интерфейс (см. rep1).

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