Versão TypeScript:
todas as noites (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;
}
Comportamento esperado:
Ao compilar isso com verificações estritas de nulos, eu esperaria que fosse compilado, uma vez que as variáveis desestruturadas foram marcadas como opcionais, porque isso funciona:
export interface QueryMetadataFactory {
(selector: Type | string, whatever?: {
descendants?: boolean;
read?: any;
}): ParameterDecorator;
new (selector: Type | string, whatever?: {
descendants?: boolean;
read?: any;
}): QueryMetadata;
}
Comportamento real:
Após a compilação:
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 é limítrofe. A função
function foo({ a, b }?: { a: number, b: number }) {
}
é na verdade um erro porque o argumento que você está tentando desestruturar pode ser undefined
. Portanto, implementar a assinatura exata que você tem em seu exemplo não seria possível. Agora, se você alterar a declaração para
function foo({ a, b }: { a: number, b: number } = { a: 0, b: 0 }) {
}
não é mais um erro porque undefined
seria substituído pelo valor padrão. Ainda assim, da perspectiva do chamador, o parâmetro ainda é opcional e se você gerar um arquivo de declaração, nós cuspimos a declaração
declare function foo({ a, b }?: { a: number, b: number }): void;
o que causa um erro. E _isso_ é um bug.
Como um aparte, sugiro evitar parâmetros de desestruturação em assinaturas de não implementação. Eles são realmente um detalhe de implementação, ou seja, se a implementação da função destrói o argumento ou apenas usa o acesso à propriedade, não deveria preocupar o chamador. No entanto, no caso do arquivo de declaração, como não temos nenhum nome de parâmetro real para emitir, nós (relutantemente) emitimos o padrão de desestruturação e, portanto, precisamos corrigir o bug.
Comentários muito úteis
Este é limítrofe. A função
é na verdade um erro porque o argumento que você está tentando desestruturar pode ser
undefined
. Portanto, implementar a assinatura exata que você tem em seu exemplo não seria possível. Agora, se você alterar a declaração paranão é mais um erro porque
undefined
seria substituído pelo valor padrão. Ainda assim, da perspectiva do chamador, o parâmetro ainda é opcional e se você gerar um arquivo de declaração, nós cuspimos a declaraçãoo que causa um erro. E _isso_ é um bug.
Como um aparte, sugiro evitar parâmetros de desestruturação em assinaturas de não implementação. Eles são realmente um detalhe de implementação, ou seja, se a implementação da função destrói o argumento ou apenas usa o acesso à propriedade, não deveria preocupar o chamador. No entanto, no caso do arquivo de declaração, como não temos nenhum nome de parâmetro real para emitir, nós (relutantemente) emitimos o padrão de desestruturação e, portanto, precisamos corrigir o bug.