ยังไงเพื่อตัวกรองเป็น TypeScript อาเรย์จากพื้นฐานบางที-ยังไม่ระบุวันที่เป็นข้อความรายการสิ่งทรัพย์สิน?

0

คำถาม

ครูปแบบ api จะคืนค่ากลับมาเป็นผลลัพธ์เหมือนกับวัตถุอย่างนึงกับมากกว่าพันค่าในรูปแบบต่อไปนี้:

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

ฉันอยากจะกรองรายการในสิ่งซึ่งเป็นมากกว่า 90 วันเก่าโดยไม่ต้อ iterate ทั้งหมดรายการใช้สำหรับเรื่อยๆ หรือจะพูดอีกอย่างฉันต้องการจะทำอะไรแบบนี้ด้านล่างนี้แต่มันไม่ได้ผลหรอก

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

ตามทรัพย์สินแบบ ide CreatedOn เป็นประเภท string | undefined ดังนั้นทำให้เกิดข้อผิดพลาด:ข้อโต้แย้งของประเภท 'string | undefined' ไม่ assignable ต้องพารามิเตอร์ของประเภท 'string'. ประเภท 'undefined' ไม่ assignable ต้องประเภท 'string'.

javascript typescript
2021-11-24 03:43:04
3

คำตอบที่ดีที่สุด

2

ที่ไหนสักแห่งในโครงการของคุณคุณจะมี บางอย่างเหมือน นี้:

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

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

หรือนี่(หรือในการเต้น thereof):

type Result = {
    items?: ResultItem[];
}

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

หรือมันอาจจะเป็น type แทนที่จะเป็น interface (แค่ทำให้แน่ใจว่าคุณไม่เคยใช้ class จะอธิบาย LANGUAGE ข้อมูลอย่างที่ LANGUAGE object ข้อมูลไม่สามารถเป็น class ตัวอย่างเช่เพราะว่า constructor ไม่เคยวิ่ง).

แล้วก็คุณควรจะใช้ camelCaseไม่ใช่ PascalCaseสำหรับสมาชิกในคุณสมบัติของ. ดังนั้นใช้ชื่อเหมือน createdOn แทนที่จะเป็น CreatedOn ในของคุณที่ถูกสร้าง LANGUAGE.

โชคดีที่คุณไม่จำเป็นต้องเปลี่ยนประเภท/ส่วนเชื่อมต่อแค่เปลี่ยนของคุณ TypeScript ไป อย่างปลอดภัย เช็ค .CreatedOn และ นั่น Date.parse ไม่ออกมา NaN. เหมือนแล้ว:

  • คน result.items ?? [] ส่วนหนึ่งเป็นเพราะของคุณโพส implies result.items คือ nullable หรือบางทีอาจจะ-undefined.
  • ข้อตอนที่ใช้ map กับ =>-รูปแบบงานอนว่าคุณอาจจะต้องการจะห่อของวัตถุ-literals ใน () ดังนั้น JS เครื่องยนต์ไม่ได้ตีความเรื่องการ { แล้ว } เป็นบล็อก delimiters.
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;
} );

ถึงแม้ว่าส่วนตัวแล้วฉันจะทำมันกับการเริ่มต้น filter แล้ว map ขั้นตอน:

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

หรือประยุกต์@item text character set เพิ่มเติม:

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

การเป็นทางออก:

  • ถ้าคุณอยู่ในการควบคุมของ LANGUAGE คือที่ถูกสร้างจากนั้นคุณสามารถทำให้แน่ใจว่าแน่นอน(หรือทั้งหมด)คุณสมบัติของรายการจะตั้งค่า(และไม่เคย undefined หรือ null)ดังนั้นถ้าคุณสามารถรับประกันว่าทั้ง 3 คุณสมบัติของเป็นเสมอตั้ง(ไม่ต้อง null หรือ undefined)นั้นปรับปรุงของประเภท/ส่วนเชื่อมต่อไปนี้:

    interface ResultItem {
        readonly name       : string;
        readonly createdOn  : string;
        readonly description: string;
    }
    
    • ข้อค camelCase คุณสมบัติของ.
    • Immutability ของข้อมูล เหมือนจะเป็นประโยชน์ดังนั้นทำให้แน่ใจว่าของคุณส่วนติดต่อคุณสมบัติของทุกคน readonlyทั้งหม arrays เป็ readonly T[]และนั่นคุณสมบัติของเป็นเพียง annotated กับ ? หรือ | null หรือ | undefined ขณะที่เหมาะสมแทนที่จะเป็นแค่สมมุติว่าเป็นยังไงไม่ทางใดก็ทางหนึ่ง
  • งั้นทำให้แน่ใจว่าคุณใช้ strictNullChecks ในของคุณ tsconfig.json หรือ tsc ตัวเลือก! -ที่จริงใช้ strict ตลอด!

  • ยังคิดถึงการเปลี่ยน LANGUAGE DTO จากใช้ string ตัวแทนของวัน(มี gurantees เรื่องเขตเวลา?) ต้องการเป็น natively สามารถอ่านระบบยูนิกซ์วันที่และเวลา(หน่วยเป็นมิลลิวินาที),แบบนั้นคุณสามารถหลีกเลี่ยงปัญหากับ Date.parse ทั้งหมด:

e.g.:

ผลลัพธ์.à™àà§à•à£àà™:

public class ResultItem
{
    [JsonProperty( "createdOn" )]
    public DateTimeOffset CreatedOn { get; }

    [JsonProperty( "createdOnUnix" )]
    public Int64 CreatedOnUnix => this.CreatedOn.ToUnixTimeMilliseconds();
}

ผลลัพธ์.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 );

...มันเป็นนัดเดียว-สายงาน


ที่อยู่เหนือสามารถสร้างแม้จะง่ายกว่าเป็นเวลาประทับระบบยูนิกซ์เป็นแค่ integers นั่นคือโดยตรง comparable ดังนั้น new Date() ได้ค้นข้างใน filterเหมือนแล้ว:

const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const ninetyDaysAgoUnix = ninetyDaysAgo.getTime();

const newResult = items.filter( e => e.createdOnUnix < ninetyDaysAgoUnix );
2021-11-24 04:21:52
1

สมมติว่าคุณมีส่วนเชื่อมต่อถูกกำหนดแบบนี้...

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 นามเด็กเล่สาธิต

2021-11-24 04:01:43

ขออภัยของฉัน ignorance(และมันก็ค่อนข้างใหญ่หลุมของฉัน)อะไร ({ CreatedOn, ...item }) => ({ ทำกันแน่? ฉันไม่เคยเห็นแพร่กระจายออกไปโอเปอเรเตอร์ ... ใช้ฟังก์ชันเป็นพารามิเตอร์รายการในเวลาเดียวกันเหมือนกับวัตถุอย่างนึ-จริง.
Dai

@ได extracts บางคนที่ชื่อคุณสมบัติของ(CreatedOnและเก็บที่เหลืออยู่ item. โดยพื้นฐานแล้วเป็นปุ่มพิมพ์ลัดสำหรับ (obj) => { const { a, b, ...rest } = obj; ...
Phil
-1

รหัสก็คือหาย ) ของตัวกรองฟังก์ชัน

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


2021-11-24 04:23:03

คำตอบของคุณไม่อยู่ tsc's ชนิดข้อผิดพลาด.
Dai

อย่างที่มันเป็นปัจจุบันเขียนของคุณคำตอบคือไม่แน่ชัด โปรด แก้ไข เพื่อเพิ่มรายละเอียดเพิ่มเติมนั้นจะช่วยคนอื่นเข้าใจว่าที่อยู่คำถามถาม คุณสามารถหาข้อมูลมากกว่าที่จะเขียนคำตอบที่ดี ในการช่วยเหลือศูนย์กลาง.
Community

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่