Undeva în proiectul dumneavoastră va trebui ceva de genul asta:
interface Result {
readonly items: readonly ResultItem[] | null;
}
interface ResultItem {
readonly Name : string;
readonly CreatedOn : string | undefined;
readonly Description: string;
}
sau asta (sau variante ale acestora):
type Result = {
items?: ResultItem[];
}
interface ResultItem {
Name : string;
CreatedOn? : string;
Description: string;
}
Sau poate fi un type
în loc de un interface
(doar asigurați-vă că nu utilizați niciodată class
pentru a descrie date JSON, ca JSON object
datele nu pot fi o class
exemplu, deoarece constructorul nu ruleaza).
De asemenea, ar trebui să fie folosind camelCase
nu PascalCase
pentru statele proprietăți. Deci, utilizarea de nume ca createdOn
în loc de CreatedOn
în generat JSON.
Din fericire, nu Aveți nevoie pentru a schimba tipurile/interfaces, schimbă-ți mașina de Scris pentru a în condiții de siguranță verificați .CreatedOn
și că Date.parse
nu a returnat NaN
. Astfel:
- La
result.items ?? []
o parte este pentru post presupune result.items
este null sau poate-undefined
.
- Notă atunci când se utilizează
map
cu o =>
-stil funcție de care ați putea avea nevoie să-și încheie obiect-literali în ()
deci motorului JS nu se interpreteze {
și }
ca delimitatori de bloc.
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;
} );
Deși, personal, aș face-o cu o inițială filter
și map
pașii de mai jos:
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 ) );
sau simplificate în continuare:
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 );
O soluție și mai bună:
Dacă sunteți în controlul de modul în care JSON este generat atunci vă puteți asigura că anumite (sau toate) element de proprietăți va fi întotdeauna stabilit (și deci nu undefined
sau null
), deci, dacă vă pot garanta că toate cele 3 proprietăți sunt întotdeauna setat (nu null
sau undefined
) apoi actualizați tipuri/interfețe pentru acest lucru:
interface ResultItem {
readonly name : string;
readonly createdOn : string;
readonly description: string;
}
- Notă
camelCase
proprietăți.
- Imutabilitatea de date este un beneficiu imens, astfel încât asigurați-vă că interfața de proprietăți sunt toate
readonly
toate matricele sunt readonly T[]
și că proprietățile sunt doar adnotat cu ?
sau | null
sau | undefined
ca-caz în loc de pur și simplu presupunând că într-un fel sau altul.
Deci, asigurați-vă că utilizați strictNullChecks
în tsconfig.json
sau tsc
opțiuni! - de fapt, trebuie doar să utilizați strict
întotdeauna!
De asemenea, luați în considerare schimbarea JSON DTO la utilizarea unui string
reprezentarea o Data (sunt acolo orice garanțiilor despre orar?) pentru a fi un nativ poate fi citit Unix timestamp (în milisecunde), în acest fel puteți evita problemele cu Date.parse
în întregime:
de exemplu:
Rezultatul.cs:
public class ResultItem
{
[JsonProperty( "createdOn" )]
public DateTimeOffset CreatedOn { get; }
[JsonProperty( "createdOnUnix" )]
public Int64 CreatedOnUnix => this.CreatedOn.ToUnixTimeMilliseconds();
}
Rezultatul.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 );
...așa că e o singură linie de muncă.
Cele de mai sus pot fi făcute chiar mai simplu ca Unix timestamp-uri sunt doar numere întregi, care sunt direct comparabile, deci new Date()
pot fi evitate în interiorul filter
astfel:
const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const ninetyDaysAgoUnix = ninetyDaysAgo.getTime();
const newResult = items.filter( e => e.createdOnUnix < ninetyDaysAgoUnix );
({ CreatedOn, ...item }) => ({
fac, mai exact? N-am văzut răspândirea operator...
folosit într-o listă de parametri funcție, în același timp, ca un obiect-literal.