簡體   English   中英

如何根據可能未定義的日期作為字符串項 object 屬性過濾 TypeScript 數組?

[英]How to filter a TypeScript array based on maybe-undefined date-as-string item object property?

API 以 object 的形式返回結果,其中包含以下格式的一千多個值:

result = {
  "items": [
            {
              "Name": "abc",
              "CreatedOn": "2017-08-29T15:21:20.000Z",
              "Description": "xyz"
            },
            {
              "Name": "def",
              "CreatedOn": "2021-05-21T15:20:20.000Z",
              "Description": "cvb"
            }
          ]
}

我想過濾 object 中超過 90 天的項目,而不必使用 for 循環迭代所有項目。 換句話說,我想在下面做這樣的事情,但這不起作用。

var currentDate = new Date();
var newResult = result.items?.filter(function(i) {
    return ((currentDate - Date.parse(i.CreatedOn)) > 90);
}

根據 IDE 屬性CreatedOnstring | undefined string | undefined ,因此它會引發錯誤:Argument of type 'string | undefined' 'string | undefined'不能分配給'string'類型的參數。 類型'undefined'不可分配給類型'string'

在您的項目中的某個地方,您將擁有如下內容:

interface Result {
    readonly items: readonly ResultItem[] | null;
}

interface ResultItem {
    readonly Name       : string;
    readonly CreatedOn  : string | undefined;
    readonly Description: string;
}

或這個(或其變體):

interface Result {
    items?: ResultItem[];
}

interface ResultItem {
    Name       : string;
    CreatedOn? : string;
    Description: string;
}

Or it may be a type instead of an interface (just make sure you never use class to describe JSON data, as JSON object data cannot be a class instance because the constructor never runs).


您不需要更改類型/接口,只需更改您的 TypeScript 以安全檢查.CreatedOn並且Date.parse沒有返回NaN 像這樣:

result.items?? []部分是因為您的帖子暗示result.items可以為空或可能undefined )。

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;
} );

雖然我個人會使用初始map步驟和isNaN的另一個filter步驟來完成,如下所示:

const items       = result.items ?? [];
const currentDate = new Date();

const newResult = items
    .map( e => { ...e, CreatedOn2:Date.parse( e.CreatedOn ) } )
    .filter( e => !isNaN( e.CreatedOn2 ) )
    .filter( e => ( currentDate - e.CreatedOn2 ) > 90 ) );

假設你有這樣定義的接口......

interface Item {
  Name: string,
  Description: string,
  CreatedOn?: string // note the optional "?"
}

interface Result {
  items?: Item[] // also optional according to your code
}

並且您想過濾超過 90 天的項目(不包括沒有CreatedOn的項目),然后試試這個

interface ItemWithDate extends Omit<Item, "CreatedOn"> {
  CreatedOn?: Date // real dates, so much better than strings
}

const result: Result = { /* whatever */ }

const items: ItemWithDate[] = result.items?.map(({ CreatedOn, ...item }) => ({
  ...item,
  CreatedOn: CreatedOn ? new Date(CreatedOn) : undefined
})) ?? []

const dateThreshold = new Date()
dateThreshold.setDate(dateThreshold.getDate() - 90)

const newItems = items.filter(({ CreatedOn }) =>
  CreatedOn && CreatedOn < dateThreshold)

TypeScript 游樂場演示

代碼丟失過濾器 function

var currentDate = new Date();
var newResult = result.items?.filter(function(i) {
    return ((currentDate - Date.parse(i.CreatedOn)) > 90);
}  ) //<= misss


暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM