Tìm kiếm trang web

Typescript: Ép loại tổng quát mặc định là `any` thay vì `{}`


Tôi có một hàm a mà nên trả về any nếu không có kiểu tổng quát nào được cung cấp, T nếu có.

var a = function<T>() : T  {
    return null;
}
var b = a<number>();    //number
var c = a();    //c is {}. Not what I want... I want c to be any.
var d; //any
var e = a<typeof d>();  //any

Điều đó có khả thi không? (Rõ ràng là không thay đổi các cuộc gọi hàm. Hay nói cách khác là không dùng a<any>().)

Câu trả lời #1

Có khả thi không? (Rõ ràng là không thay đổi các lệnh gọi hàm. Hay nói cách khác là không dùng a().)

Vâng.

Tôi tin rằng trong trường hợp của bạn, bạn sẽ làm

var a = function<T = any>() : T  {
    return null;
}

Các giá trị mặc định tổng quát đã được giới thiệu trong TS 2.3.

Các kiểu mặc định cho các tham số kiểu tổng quát có cú pháp như sau:

TypeParameter :
  BindingIdentifier Constraint? DefaultType?

DefaultType :
  `=` Type

Ví dụ:

class Generic<T = string> {
  private readonly list: T[] = []

  add(t: T) {
    this.list.push(t)
  }

  log() {
    console.log(this.list)
  }

}

const generic = new Generic()
generic.add('hello world') // Works
generic.add(4) // Error: Argument of type '4' is not assignable to parameter of type 'string'
generic.add({t: 33}) // Error: Argument of type '{ t: number; }' is not assignable to parameter of type 'string'
generic.log()

const genericAny = new Generic<any>()
// All of the following compile successfully
genericAny.add('hello world')
genericAny.add(4)
genericAny.add({t: 33})
genericAny.log()

Xem https://github.com/Microsoft/TypeScript/wiki/Roadmap#23-april-2017 và https://github.com/Microsoft/TypeScript/pull/13487

Câu trả lời #2

Đi xa hơn một chút cho một ứng dụng hơi khác, nhưng bạn cũng có thể đặt các đối số kiểu mặc định thành một đối số kiểu khác.

Ví dụ, hãy lấy:

class Foo<T1 = any, T2 = T1> {
    prop1: T1;
    prop2: T2;
}

và vì vậy:

const foo1 = new Foo();
typeof foo1.prop1 // any
typeof foo1.prop1 // any

const foo2 = new Foo<string>();
typeof foo2.prop1 // string
typeof foo2.prop2 // string

const foo3 = new Foo<string, number>();
typeof foo3.prop1 // string
typeof foo3.prop1 // number

Bài viết liên quan