Někde ve vašem projektu, budete mít něco jako toto:
interface Result {
readonly items: readonly ResultItem[] | null;
}
interface ResultItem {
readonly Name : string;
readonly CreatedOn : string | undefined;
readonly Description: string;
}
nebo tento (nebo jejich varianty):
type Result = {
items?: ResultItem[];
}
interface ResultItem {
Name : string;
CreatedOn? : string;
Description: string;
}
Nebo to může být type
místo interface
(jen ujistěte se, že jste nikdy použít class
k popisu dat JSON, jako JSON object
data nemohou být class
instance, protože konstruktor nikdy běží).
Také byste měli být pomocí camelCase
ne PascalCase
pro členské vlastnosti. Takže používat názvy jako createdOn
místo CreatedOn
na váš vygenerovaný JSON.
Naštěstí nemusíte měnit typů/rozhraní, stačí změnit svůj TypeScript bezpečně zkontrolovat .CreatedOn
a že Date.parse
nevrátil NaN
. Tak jako:
- Na
result.items ?? []
součástí je proto, že váš příspěvek znamená result.items
je s možnou hodnotou null nebo možná-undefined
.
- Poznámka: při použití
map
s =>
-styl funkce, které můžete potřebovat zabalit objekt-literály v ()
takže JS motor nemá interpretovat {
a }
jako oddělovače bloku.
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;
} );
I když osobně bych to udělal s počáteční filter
a map
kroky:
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 ) );
nebo zjednodušené dále:
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 );
Ještě lepší řešení:
Pokud jste v kontrole toho, jak JSON je generován pak můžete zajistit, že určité (nebo všechny) vlastnosti položky bude vždy být (a tak nikdy undefined
nebo null
), takže pokud vám nemůže zaručit, že všechny 3 vlastnosti jsou vždy sada (nikdy null
nebo undefined
), pak aktualizovat svůj typů/rozhraní:
interface ResultItem {
readonly name : string;
readonly createdOn : string;
readonly description: string;
}
- Poznámka:
camelCase
vlastnosti.
- Neměnnost dat , je velkým přínosem, takže ujistěte se, že rozhraní vlastnosti jsou všechny
readonly
všechny pole jsou readonly T[]
a které vlastnosti jsou pouze komentovaný s ?
nebo | null
nebo | undefined
jako vhodné místo jednoduše za předpokladu, že jedna cesta nebo jiný.
Takže ujistěte se, že používáte strictNullChecks
ve vašem tsconfig.json
nebo tsc
možností! - ve skutečnosti, stačí použít strict
vždy!
Také zvážit změnu JSON DTO od používání string
vyjádření Data (jsou tam nějaké garantuje o časovém pásmu?) být nativně čitelné Unix timestamp (v milisekundách), že způsob, jak se můžete vyhnout problémům s Date.parse
zcela:
např.:
Výsledek.cs:
public class ResultItem
{
[JsonProperty( "createdOn" )]
public DateTimeOffset CreatedOn { get; }
[JsonProperty( "createdOnUnix" )]
public Int64 CreatedOnUnix => this.CreatedOn.ToUnixTimeMilliseconds();
}
Výsledek.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 );
...tak to je single-line práci.
Výše uvedené může být ještě jednodušší, protože Unix časová razítka jsou jen celá čísla, která jsou přímo srovnatelné, takže new Date()
se lze vyhnout uvnitř filter
, tak jako:
const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const ninetyDaysAgoUnix = ninetyDaysAgo.getTime();
const newResult = items.filter( e => e.createdOnUnix < ninetyDaysAgoUnix );
({ CreatedOn, ...item }) => ({
přesně udělat? Nikdy jsem neviděl šíření operátora...
používá se v seznamu parametrů funkce zároveň jako objekt-doslovný.