Me pregunto cómo puedo asignar un valor a una clave que depende de otra clave dentro de ese mismo objeto. En este caso quiero decir que si el animal tiene dueño NO es alimento pero si no tiene dueño ES alimento. Entonces, en mi ejemplo, el objeto animal debería evaluarse como verdadero y animal2 debería evaluarse como falso, pero no lo hacen.
> I have tried isFood: animal.owner ? false: true > I have tried isFood: animal.hasOwnProperty("owner") ? false: true > I have tried isFood: "owner" in animal ? false: true > I have tried isFood: this.owner ? false: true interface personInterface { name: string, age: number, isMember: boolean }; interface animalInterface<T> { owner?: T, sound: string, species: string, isFood: boolean } let person: personInterface; person = { name: "justin", age: 30, isMember: true } let animal: animalInterface<personInterface>; let animal2: animalInterface<personInterface>; animal = { owner: {...person}, sound: "Woof", species: "Dog", isFood: this.owner ? false: true } animal2 = { sound: "Woof", species: "Dog", isFood: this.owner ? false: true }Para lograrlo, necesita usar uniones discriminadas :
interface PersonInterface { name: string, age: number, isMember: boolean }; interface AnimalInterfaceBase<T> { owner?: T, sound: string, species: string, isFood: boolean } type WithOwner<T> = { owner: T, sound: string, species: string, isFood: false } type WithoutOwner = { sound: string, species: string, isFood: true } type AnimalInterface<T> = WithOwner<T> | WithoutOwner let person: PersonInterface; person = { name: "justin", age: 30, isMember: true } let animal: AnimalInterface<PersonInterface>; let animal2: AnimalInterface<PersonInterface>; animal = { owner: person, sound: "Woof", species: "Dog", isFood: false } animal2 = { owner: person, // expected error sound: "Woof", species: "Dog", isFood: true }PD Es convencional escribir en mayúsculas los nombres de las interfaces.
this puede variar dependiendo de dónde se use, dentro de una función o globalmente. Para hacer referencia al objeto actual y seguir accediendo a la clave como una propiedad, puede usar get accessor como se muestra a continuación. Puedes leer más sobre cómo get accesor aquí .
animal = { owner: { ...person }, sound: "Woof", species: "Dog", get isFood() { // Here this refers to current object return this.owner ? false : true } } animal2 = { sound: "Woof", species: "Dog", get isFood() { return this.owner ? false : true } } console.log(animal.isFood); console.log(animal2.isFood);En este caso, podría usar tipos de unión etiquetados. Básicamente, crea dos interfaces y las distingue por una propiedad, en su caso isFood :
interface BaseAnimalInterface { sound: string; species: string; isFood: boolean; } interface AnimalInterface extends BaseAnimalInterface { isFood: true; } interface PetInterface<T = PersonInterface> extends BaseAnimalInterface { owner: T; isFood: false; } type AnimalType = AnimalInterface | PetInterface; Luego, si verifica esa propiedad en una instrucción if/switch , obtendrá el tipo adecuado:
function playSound(animal: AnimalType): void { if (animal.isFood) { // Casted automatically to `AnimalInterface` } else { // Casted automatically to `PetInterface` } }