Em algum lugar em seu projeto, você terá algo como isto:
interface Result {
readonly items: readonly ResultItem[] | null;
}
interface ResultItem {
readonly Name : string;
readonly CreatedOn : string | undefined;
readonly Description: string;
}
ou este (ou variações do mesmo):
type Result = {
items?: ResultItem[];
}
interface ResultItem {
Name : string;
CreatedOn? : string;
Description: string;
}
Ou pode ser um type
em vez de um interface
(apenas certifique-se de que você nunca usa, class
para descrever dados JSON, como JSON object
dados não pode ser um class
instância porque o construtor nunca é executado).
Além disso, você deve estar usando camelCase
, não PascalCase
para propriedades de membro. Portanto, use nomes como createdOn
em vez de CreatedOn
em sua gerado JSON.
Felizmente, Você não precisa alterar os tipos de interfaces, basta alterar o TypeScript para segurança de seleção .CreatedOn
e que Date.parse
não retorno NaN
. Assim:
- O
result.items ?? []
parte é por causa do seu post implica result.items
é anulável ou talvez-undefined
.
- Nota quando utilizar
map
com um =>
-função de estilo que você pode precisar para moldar objeto-literais em ()
assim, a JS motor não interpreta o {
e }
como delimitadores de bloco.
const result: Result = ...
const currentDate = new Date();
const newResult = (result.items ?? []).filter( e => {
if( typeof e.CreatedOn === 'string' ) {
const parsed = Date.parse( e.CreatedOn );
if( !isNaN( parsed ) ) {
return ( currentDate - parsed ) > 90;
}
}
return false;
} );
Embora, pessoalmente, eu gostaria de fazê-lo com uma inicial filter
e map
passos:
const items = result.items ?? [];
const currentDate = new Date();
const newResult = items
.filter( e => typeof e.CreatedOn === 'string' )
.map( e => ( { ...e, CreatedOn2: Date.parse( e.CreatedOn ) } ) )
.filter( e => !isNaN( e.CreatedOn2 ) )
.filter( e => ( currentDate - e.CreatedOn2 ) > 90 ) );
ou mais simplificadas:
const items = result.items ?? [];
const currentDate = new Date();
const newResult = items
.filter( e => typeof e.CreatedOn === 'string' )
.map( e => Object.assign( e, { createdOn2: Date.parse( e.CreatedOn ) )
.filter( e => !isNaN( e.CreatedOn2 ) && ( currentDate - e.CreatedOn2 ) > 90 );
Uma solução ainda melhor:
Se você está no controle de como o JSON é gerado, em seguida, você pode assegurar-se de que algumas (ou todas) as propriedades do item será sempre definida (e por isso nunca undefined
ou null
), assim se pode garantir que todas as 3 propriedades são sempre definidas (nunca null
ou undefined
), em seguida, atualizar a sua tipos/interfaces este:
interface ResultItem {
readonly name : string;
readonly createdOn : string;
readonly description: string;
}
- Nota o
camelCase
propriedades.
- A imutabilidade dos dados é um benefício enorme, por isso certifique-se de que suas propriedades de interface são todos
readonly
, todas as matrizes são readonly T[]
e que as propriedades são apenas anotado com ?
ou | null
ou | undefined
como apropriado, em vez de simplesmente assumindo uma forma ou de outra.
Portanto, certifique-se de usar strictNullChecks
em seu tsconfig.json
ou tsc
opções! - na verdade, é só usar strict
sempre!
Também considere alterar seu JSON DTO do uso de um string
representação de uma Data (há qualquer gurantees sobre o fuso horário?) para ser um nativamente legível Unix timestamp (em milissegundos), de que forma você pode evitar problemas com a Date.parse
inteiramente:
por exemplo:
Resultado.cs:
public class ResultItem
{
[JsonProperty( "createdOn" )]
public DateTimeOffset CreatedOn { get; }
[JsonProperty( "createdOnUnix" )]
public Int64 CreatedOnUnix => this.CreatedOn.ToUnixTimeMilliseconds();
}
Resultado.ts:
interface ResultItem {
readonly createdOn : string;
readonly createdOnUnix: number;
}
const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const newResult = items.filter( e => new Date( e.createdOnUnix ) < ninetyDaysAgo );
...dessa forma, é uma única linha de trabalho.
O acima pode ser feita até mesmo mais simples como timestamps Unix são apenas números inteiros que são diretamente comparáveis, de modo new Date()
pode ser evitado dentro do filter
assim:
const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const ninetyDaysAgoUnix = ninetyDaysAgo.getTime();
const newResult = items.filter( e => e.createdOnUnix < ninetyDaysAgoUnix );
({ CreatedOn, ...item }) => ({
fazer, exatamente? Eu nunca vi a propagação do operador...
usado em uma lista de parâmetros de função ao mesmo tempo como um objeto literal.