ค้นหาเว็บไซต์

กำหนดประเภทของฟังก์ชันอย่างเคร่งครัดที่รับวัตถุ แก้ไขค่าของมัน และส่งคืนใน TypeScript


ฉันต้องการสร้างฟังก์ชันที่สร้างวัตถุใหม่โดยมีคีย์เหมือนกับวัตถุต้นฉบับที่ได้รับ แต่มีค่าเท่ากับ null

งั้นก็...

function nullify(arg) {
  var returnObj = {}

  for (var key in arg) {
    returnObj[key] = null
  }

  return returnObj
}

ฉันต้องการเพิ่มประเภทให้กับฟังก์ชันนี้เพื่อให้ตัวคอมไพเลอร์ TypeScript แสดงคำเตือนเมื่อฉันพยายามเข้าถึงคุณสมบัติที่ไม่มีอยู่ในวัตถุที่ส่งคืน ตัวอย่างเช่น:

var nulled = nullify({
  a: 1,
  b: 2
})

console.log(nulled.foobar) // Error `foobar` doesn't exist.

อะไรแบบนั้นเป็นไปได้ไหม? อาจจะโดยใช้ generics และ keyof?

ขอโทษนะครับ ผมเป็นมือใหม่ TypeScript แบบเต็มตัว

คำตอบ #1

เมื่อใช้ TS 2.1 คุณสามารถใช้ชนิดที่แมปได้ โดยค่าเริ่มต้น ชนิดมักจะเป็น type | number อย่างไรก็ตาม หากคุณมีการตรวจสอบอย่างเข้มงวดสำหรับวัตถุที่เป็น null การใช้ชนิดที่แมปจะเป็นวิธีที่บรรยายได้ชัดเจนมากกว่า

type Nullified<T> = {
    [P in keyof T]?: null
}

function nullify<T>(arg:T) : Nullified<T> {
  var returnObj = {}

  for (var key in arg) {
    returnObj[key] = null
  }

  return returnObj
}

คำตอบ #2

คุณสามารถทำสิ่งนี้ได้โดยใช้ generics แบบนี้:

function nullify<T>(arg: T): T {
    var returnObj = {} as T;

    for (var key in arg) {
        returnObj[key] = null
    }

    return returnObj
}

การใช้งาน :

var nulled = nullify({
    a: 1,
    b: 2
})

console.log(nulled.a); // No problem
console.log(nulled.x); // Compiler error  Property 'x' does not exist on type '{ a: number; b: number; }'.

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

ขยายและแก้ไขคำตอบของ Paarth: เมื่อใช้ การตรวจสอบค่า null อย่างเข้มงวด และมี TypeScript 2.1 หรือสูงกว่า คุณอาจต้องการประกาศชนิดที่ส่งกลับเพื่ออนุญาตให้ค่าของคุณสมบัติเป็น null:

// Defined mapped type Nullified from type T.
// Mapped type has all the same properties with the 
// same types except that the properties in Nullified
// can also be null
type Nullified<T> = {
    [P in keyof T]: T[P] | null
}

function nullify<T>(arg: T): Nullified<T> {
    var returnObj = {} as Nullified<T>;

    for (var key in arg) {
        returnObj[key] = null
    }
    return returnObj
}