Tìm kiếm trang web

typescript - Định nghĩa kiểu cho các giá trị cụ thể của mảng đối tượng


Giả sử tôi có mảng đối tượng sau:

const shapes = [
    { name: 'circle', color: 'blue' },
    { name: 'square', size: 42 },
    { name: 'rectangle', color: 'blue' }
];

type ShapeName = typeof shapes[number]['name']; // ShapeName is type 'string' but I would want: 'circle'|'square'|'rectangle'

Tôi muốn có một kiểu "ShapeName" chứa các giá trị của các thuộc tính name trong các đối tượng của tôi. Tuy nhiên, khi cố gắng làm điều này chỉ cho tôi kiểu 'string'. Có cách nào để thu hẹp nó thành 'circle'|'square'|'rectangle' không.

Ví dụ TsPlayground.

Câu trả lời #1

Khi bạn định nghĩa một mảng các đối tượng, điều hợp lý là bạn có thể thêm nhiều giá trị hơn vào nó sau này. TypeScript giả định đây là trường hợp và bạn có thể thêm nhiều đối tượng sau này... điều này có thể hoặc có thể không chỉ có ba giá trị được đề cập cho thuộc tính name. Ngoài ra, nói chung, TypeScript suy ra rằng name là một string, điều này thường là những gì bạn muốn một đối tượng được suy ra. Vì vậy, thông thường, suy luận string là một ý tưởng rất tốt cho hầu hết các trường hợp.

Để nói với TypeScript rằng đây là một mảng cố định, bạn cần sử dụng Khẳng định Const (Const Assertion). Điều này biến các literal mảng thành các tuple readonly. Như thế này:

const shapes = [
  { name: "circle", color: "blue" },
  { name: "square", size: 42 },
  { name: "rectangle", color: "blue" },
] as const;

type ShapeName = typeof shapes[number]["name"];
// type ShapeName = "circle" | "square" | "rectangle"

Đây là liên kết TS Playground: https://tsplay.dev/m029ow