En ngIf necesita devolver un booleano del valor del objeto.
var a = {"c" : "b","f": "g"}
a["c"] => 'b'
(a && a["c"]) => 'b' // por qué aquí no devuelve verdadero
a && a["c"] => 'b' // Cómo devolver un booleano a partir de un valor aquí
!!( a && a["c"]) => verdadero // ¿es la forma correcta de devolver verdadero o alguna otra forma mejor disponible?
<button title="Submit" *ngIf="!!(a && a["c"])">Submit</button>
"por que aqui no esta volviendo verdad"
(a && a["c"]) devuelve a si a es falso y a["c"] si a es verdadero. Un objeto siempre es verdadero, por lo tanto (a && a["c"]) devuelve "b" .
"Cómo devolver un booleano de un valor aquí"
!! es una operación común para convertir un valor verdadero en verdadero y un valor falso en falso.
"¿Es la forma correcta de devolver verdadero o cualquier otra forma mejor disponible?"
Es correcto y usaría !!(a && a["c"]) para convertir (a && a["c"]) a booleano.
Puedes acortarlo con !!a?.c ( encadenamiento opcional ):
<button title="Submit" *ngIf="!!a?.c">Submit</button>o incluso
<button title="Submit" *ngIf="a?.c">Submit</button>si su configuración de TypeScript lo permite.
Recomiendo revisar la lista de valores verdaderos y falsos . A veces los resultados pueden ser muy sorprendentes.