Версия TypeScript:
по ночам (1.9.0-dev.20160217)
Код
export interface QueryMetadataFactory {
(selector: Type | string, {descendants, read}?: {
descendants?: boolean;
read?: any;
}): ParameterDecorator;
new (selector: Type | string, {descendants, read}?: {
descendants?: boolean;
read?: any;
}): QueryMetadata;
}
Ожидаемое поведение:
При компиляции со строгими проверками на null я ожидал, что это будет компилироваться, поскольку деструктурированные переменные были помечены как необязательные, потому что это работает:
export interface QueryMetadataFactory {
(selector: Type | string, whatever?: {
descendants?: boolean;
read?: any;
}): ParameterDecorator;
new (selector: Type | string, whatever?: {
descendants?: boolean;
read?: any;
}): QueryMetadata;
}
Фактическое поведение:
При компиляции:
node_modules/@angular/core/src/metadata.d.ts(356,32): error TS2459: Type '{ descendants?: boolean | undefined; read?: any; } | undefined' has no property 'descendants' and no string index signature.
node_modules/@angular/core/src/metadata.d.ts(356,45): error TS2459: Type '{ descendants?: boolean | undefined; read?: any; } | undefined' has no property 'read' and no string index signature.
node_modules/@angular/core/src/metadata.d.ts(360,36): error TS2459: Type '{ descendants?: boolean | undefined; read?: any; } | undefined' has no property 'descendants' and no string index signature.
node_modules/@angular/core/src/metadata.d.ts(360,49): error TS2459: Type '{ descendants?: boolean | undefined; read?: any; } | undefined' has no property 'read' and no string index signatu
Этот пограничный. Функция
function foo({ a, b }?: { a: number, b: number }) {
}
на самом деле является ошибкой, потому что аргумент, который вы пытаетесь деструктурировать, может быть undefined
. Таким образом, реализовать точную подпись в вашем примере было бы невозможно. Теперь, если вы измените объявление на
function foo({ a, b }: { a: number, b: number } = { a: 0, b: 0 }) {
}
это больше не ошибка, потому что undefined
будет заменено значением по умолчанию. Тем не менее, с точки зрения вызывающих абонентов параметр по-прежнему является необязательным, и если вы сейчас создадите файл объявления, мы выплюнем объявление
declare function foo({ a, b }?: { a: number, b: number }): void;
что вызывает ошибку. И _это_ ошибка.
Кроме того, я бы посоветовал избегать параметров деструктуризации в сигнатурах, не связанных с реализацией. На самом деле они являются деталями реализации, т.е. разрушает ли реализация функции аргумент или просто использует доступ к свойствам, это не должно действительно беспокоить вызывающего. Однако в случае с файлом объявления, поскольку у нас нет фактического имени параметра, которое нужно передать, мы (неохотно) испускаем шаблон деструктуризации, и поэтому нам нужно исправить ошибку.
Самый полезный комментарий
Этот пограничный. Функция
на самом деле является ошибкой, потому что аргумент, который вы пытаетесь деструктурировать, может быть
undefined
. Таким образом, реализовать точную подпись в вашем примере было бы невозможно. Теперь, если вы измените объявление наэто больше не ошибка, потому что
undefined
будет заменено значением по умолчанию. Тем не менее, с точки зрения вызывающих абонентов параметр по-прежнему является необязательным, и если вы сейчас создадите файл объявления, мы выплюнем объявлениечто вызывает ошибку. И _это_ ошибка.
Кроме того, я бы посоветовал избегать параметров деструктуризации в сигнатурах, не связанных с реализацией. На самом деле они являются деталями реализации, т.е. разрушает ли реализация функции аргумент или просто использует доступ к свойствам, это не должно действительно беспокоить вызывающего. Однако в случае с файлом объявления, поскольку у нас нет фактического имени параметра, которое нужно передать, мы (неохотно) испускаем шаблон деструктуризации, и поэтому нам нужно исправить ошибку.