Estou tentando criar um tipo genérico que altere qualquer tipo de propriedade de um para outro. Funciona se eu criar um novo objeto com o novo tipo convertido, mas gera erros se eu tentar convertê-lo dinamicamente usando o tipo de interface antigo:
Código:
export type ConvertTypes<B, F, T> = { [K in keyof B]: B[K] extends F ? T : B[K] }
export type ConvertStringToDate<T> = ConvertTypes<T, string, Date>
interface ITest {
aa: number;
bb: string;
cc: Date;
}
// Working
const test :ITest = {
aa: 1,
bb: 'test',
cc: new Date()
}
// Working
const test2: ConvertStringToDate<ITest> = {
aa: 1,
bb: new Date(),
cc: new Date()
}
let test3: ConvertStringToDate<ITest>
// Not Working
for (let field of Object.keys(test)) {
test3[field] = typeof test[field] === 'string' ? new Date() : test[field]
}
Erros:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ConvertTypes<ITest, string, Date>'.
No index signature with a parameter of type 'string' was found on type 'ConvertTypes<ITest, string, Date>'.
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ITest'.
No index signature with a parameter of type 'string' was found on type 'ITest'.
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ITest'.
No index signature with a parameter of type 'string' was found on type 'ITest'.
O código testado deve funcionar bem e converter valores de test
variáveis para novas variáveis test3
.
À primeira vista, pode parecer bobo que o TS não lide com a iteração de chaves facilmente. Mas, ao se aprofundar, você perceberá que iterar chaves de objetos é inseguro em geral, pois um objeto pode conter quaisquer chaves adicionais não presentes em seu tipo. É por isso que o tipo da chave é inferido para
string
refletir isso. Portanto, uma maneira segura seria operar apenas com chaves conhecidas pertencentes ao tipo.No nosso caso, podemos verificar se as chaves estão associadas a um tipo de valor apropriado com proteções de tipo personalizadas:
Parque infantil
Em código real eu não me incomodaria, pois o tempo de execução é simples e basta usar
any
: