Gdzieś w projekcie u ciebie będziecoś w stylu tego:
interface Result {
readonly items: readonly ResultItem[] | null;
}
interface ResultItem {
readonly Name : string;
readonly CreatedOn : string | undefined;
readonly Description: string;
}
czy jest to (lub jego warianty):
type Result = {
items?: ResultItem[];
}
interface ResultItem {
Name : string;
CreatedOn? : string;
Description: string;
}
Lub to może być type
zamiast interface
(po prostu upewnij się, że nigdy nie używasz class
aby opisać dane JSON, jak JSON object
dane nie mogą być class
egzemplarz, bo konstruktor nigdy się nie uruchamia).
Ponadto, należy użyć camelCase
nie PascalCase
do właściwości elementów. Należy więc stosować nazwy, takie jak createdOn
zamiast CreatedOn
w generowanych przez was JSON.
Na szczęście, nie trzeba zmieniać typy/interfejsy, po prostu zmień swój tekst, aby bezpiecznie sprawdzić .CreatedOn
i co Date.parse
nie wrócił NaN
. Oto tak:
- To
result.items ?? []
częściowo dlatego, że twój post sugeruje result.items
jest nieważne lub może być-undefined
.
- Uwaga podczas korzystania z
map
z pomocą =>
-funkcja stylu, w którą może być owinąć literały obiektowe ()
w ten sposób silnik JS nie interpretuje {
i }
jako separatory bloków.
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;
} );
Chociaż osobiście bym zrobił to z początkowej filter
i map
kroki:
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 ) );
lub uproszczone jeszcze więcej:
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 );
Jeszcze lepsze rozwiązanie:
Jeśli możesz kontrolować, jak jest tworzony JSON, można zagwarantować, że niektóre (lub wszystkie) właściwości elementu zawsze będą ustawione (i dlatego nigdy undefined
lub null
), więc jeśli można zagwarantować, że wszystkie 3 właściwości zawsze ustawione (nigdy null
lub undefined
), a następnie zaktualizuj swoje typy/interfejsy do tego:
interface ResultItem {
readonly name : string;
readonly createdOn : string;
readonly description: string;
}
- Należy zwrócić uwagę na
camelCase
właściwości.
- Niezmienność danych-ogromną przewagę, więc upewnij się, że wszystkie właściwości interfejsu
readonly
wszystkie tablice są readonly T[]
i że właściwości oznaczone tylko ?
lub | null
lub | undefined
w razie potrzeby, zamiast po prostu przyjąć to, czy tamto.
Więc upewnij się, że używasz strictNullChecks
W pracy tsconfig.json
lub tsc
opcje! - w rzeczywistości, po prostu użyj strict
zawsze!
Także pomyśl o zmianie swojego JSON DTO z użytkowania string
widok daty (czy są jakieś gwarancje dotyczące strefy czasowej?) aby być początkowo czytelny datownik Unix (w milisekundach), w ten sposób można uniknąć problemów z Date.parse
w całości:
np.:
Wynik. cs:
public class ResultItem
{
[JsonProperty( "createdOn" )]
public DateTimeOffset CreatedOn { get; }
[JsonProperty( "createdOnUnix" )]
public Int64 CreatedOnUnix => this.CreatedOn.ToUnixTimeMilliseconds();
}
Wynik.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 );
...w ten sposób,to однострочная praca.
Powyższe można zrobić jeszcze łatwiej, ponieważ tymczasowe Unix-to tylko liczby, które nie są bezpośrednio porównywalne, więc new Date()
można uniknąć dostania się do środka filter
właśnie tak:
const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const ninetyDaysAgoUnix = ninetyDaysAgo.getTime();
const newResult = items.filter( e => e.createdOnUnix < ninetyDaysAgoUnix );
({ CreatedOn, ...item }) => ({
zrobić dokładnie? Nigdy nie widziałem operatora dystrybucji...
stosowany w liście parametrów funkcji jednocześnie z wynikowym znakową.