Проблемы с машинописью и условными типами с обобщениями. Мой пример использования - я хочу иметь класс, который использует дженерики. Класс может принимать либо объект, либо массив.
Если он принимает тип массива, у объектов в массиве должны быть дополнительные поля, в зависимости от интерфейса. если это просто объект, то он позволит объекту остаться прежним. То, что я до сих пор пробовал, это:
// Goal:
// Allow either of 2 scenarios:
// 1) A generic object with any properties - must not be an array.
// 2) An array of objects. The objects inside the array must contain a property called uuid of type string.
// Problem:
// type "object" is too broad, allowing for an array to "fallback"
// if it does not have the required uuid property.
interface IStorageObject {
uuid: string;
}
type Unarray<T> = T extends Array<infer U> ? U : T;
type StorageObject<T> = Unarray<T> & IStorageObject;
// We tried: Manager<T extends object | Array<StorageObject<T>>>
export class Manager<T extends Array<StorageObject<T>>> {
public data: T;
constructor(data: T) {
this.data = data;
}
}
// Test with Object
// We wish to allow objects with any properties
interface ITestObject {
property1: string;
property2: number;
}
// We have no requirement in properties ↓
const managerForObject = new Manager<ITestObject>({
property1: "123",
property2: 123,
});
// Test with Array
// Objects inside array MUST have uuid property
interface ITestObject {
property1: string;
property2: number;
}
// We have uuid property requirement for the object ↓
const managerForArray = new Manager<Array<ITestObject>>([
{
property1: "123",
property2: 123,
},
]);
// Main problem:
// This is not an error ↓
const test: object = [];
https://stackblitz.com/edit/typescript-playground-kdqapm?file=index.ts
Если вы хотите иметь go, я сделал игровую площадку с код внутри.
Заранее спасибо, и я надеюсь, что ссылка предоставит дополнительную информацию о проблеме.