Versión de TypeScript:
todas las noches (1.9.0-dev.20160217)
Código
export interface QueryMetadataFactory {
(selector: Type | string, {descendants, read}?: {
descendants?: boolean;
read?: any;
}): ParameterDecorator;
new (selector: Type | string, {descendants, read}?: {
descendants?: boolean;
read?: any;
}): QueryMetadata;
}
Comportamiento esperado:
Al compilar esto con comprobaciones nulas estrictas, esperaría que esto se compilara, ya que las variables desestructuradas se han marcado como opcionales, porque esto funciona:
export interface QueryMetadataFactory {
(selector: Type | string, whatever?: {
descendants?: boolean;
read?: any;
}): ParameterDecorator;
new (selector: Type | string, whatever?: {
descendants?: boolean;
read?: any;
}): QueryMetadata;
}
Comportamiento real:
Tras la compilación:
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
Este está en el límite. La función
function foo({ a, b }?: { a: number, b: number }) {
}
es en realidad un error porque el argumento que está intentando desestructurar podría ser undefined
. Por lo tanto, implementar la firma exacta que tiene en su ejemplo no sería posible. Ahora, si cambia la declaración a
function foo({ a, b }: { a: number, b: number } = { a: 0, b: 0 }) {
}
ya no es un error porque undefined
se reemplazaría con el valor predeterminado. Sin embargo, desde la perspectiva de las personas que llaman, el parámetro sigue siendo opcional y si ahora genera un archivo de declaración, escupimos la declaración
declare function foo({ a, b }?: { a: number, b: number }): void;
lo que provoca un error. Y eso es un error.
Aparte, sugiero evitar la desestructuración de parámetros en firmas de no implementación. Son realmente un detalle de implementación, es decir, si la implementación de la función destruye el argumento o simplemente usa el acceso a la propiedad, no debería preocupar al llamador. Sin embargo, en el caso del archivo de declaración, debido a que no tenemos un nombre de parámetro real para emitir, emitimos (a regañadientes) el patrón de desestructuración y, por lo tanto, necesitamos corregir el error.
Comentario más útil
Este está en el límite. La función
es en realidad un error porque el argumento que está intentando desestructurar podría ser
undefined
. Por lo tanto, implementar la firma exacta que tiene en su ejemplo no sería posible. Ahora, si cambia la declaración aya no es un error porque
undefined
se reemplazaría con el valor predeterminado. Sin embargo, desde la perspectiva de las personas que llaman, el parámetro sigue siendo opcional y si ahora genera un archivo de declaración, escupimos la declaraciónlo que provoca un error. Y eso es un error.
Aparte, sugiero evitar la desestructuración de parámetros en firmas de no implementación. Son realmente un detalle de implementación, es decir, si la implementación de la función destruye el argumento o simplemente usa el acceso a la propiedad, no debería preocupar al llamador. Sin embargo, en el caso del archivo de declaración, debido a que no tenemos un nombre de parámetro real para emitir, emitimos (a regañadientes) el patrón de desestructuración y, por lo tanto, necesitamos corregir el error.