Вычисляемый ключ, как ключ интерфейса, от члена enum - PullRequest
2 голосов
/ 18 апреля 2019

Я пытаюсь настроить свойство объекта, выбрав его ключ, используя вычисляемый ключ, через перечисление, как в следующем фрагменте кода.

По какой-то причине решение 1 и 2 не 'т работа.Это решения, которые я хотел бы использовать в своем коде, поскольку мне нужно присвоить значение ключу, который динамически получается из вызова API.

Что странно, по моему незнанию, так это то, что решения 4 и 5 работают, демонстрируя, что на самом деле решения 1 и 2 могут «потенциально» работать, переназначая значения свойств с помощью динамического ключа, следуякодированный ключ свойства.

Это, конечно, потому что TypeScript, пока вы предоставляете соответствующие свойства интерфейса, принимает произвольное количество дополнительных свойств, но, тем не менее, я не понимаю, почему дублированные динамические свойства работают в 4 и 5.

Тем не менее, почему решения 1 и 2 не работают?Что я делаю не так?

Спасибо за вашу помощь.


interface Cat {
    tail: boolean;
    legs: Quadruped;
}

interface Quadruped {
    totalNumber: number;
}

enum BodyParts {
    TAIL = 'tail',
    TOTAL_NUMBER = 'totalNumber'
}

let brokenArgo: Cat = { tail: true, legs: { totalNumber: 4 } };
let argo: Cat = { tail: true, legs: { totalNumber: 4 } };

argo.legs = null;

let TN = 'TOTAL_NUMBER';
let tn: BodyParts = BodyParts[TN];

// solution 1 = broken
brokenArgo.legs = { [tn]: 6 }
// solution 2 = broken
brokenArgo.legs = { [BodyParts[TN]]: 6 };
// solution 3 = working
argo.legs = { [BodyParts['TOTAL_NUMBER']]: 6 };
// solution 4 = working
argo.legs = {
    totalNumber: 0,
    [tn]: 6
};
// solution 5 = working
argo.legs = {
    totalNumber: 0,
    [BodyParts[TN]]: 6
};

Вы можете увидеть вышеприведенный скрипт, запущенный на Typescript игровая площадка здесь

1 Ответ

0 голосов
/ 23 апреля 2019

После некоторой неофициальной документации TypeScript я понял, что, поскольку объявленные интерфейсы ожидают определенного свойства (IE интерфейс не является обязательным), я должен сообщить TypeScript, что я на самом деле использую вычисляемый ключ «как» ожидаемое свойство,То есть я уверен (я ожидаю) получить от бэкэнда именно это свойство.

Выше (очень плохой пример, извините) можно исправить так:

(см. живой код здесь )

interface Cat {
    tail: boolean;
    legs: Quadruped;
}

interface Quadruped {
    totalNumber: number;
}

enum BodyParts {
    TAIL = 'tail',
    TOTAL_NUMBER = 'totalNumber'
}

let brokenArgo: Cat = { tail: true, legs: { totalNumber: 4 } };
let argo: Cat = { tail: true, legs: { totalNumber: 4 } };

argo.legs = null;

let TN = 'TOTAL_NUMBER';
let tn: BodyParts.TOTAL_NUMBER = BodyParts[TN];

// solution 1 = broken
brokenArgo.legs = { [tn]: 6 }
// solution 2 = broken
brokenArgo.legs = { [BodyParts[TN as 'TOTAL_NUMBER']]: 6 };
// solution 3 = working
argo.legs = { [BodyParts['TOTAL_NUMBER']]: 6 };
// solution 4 = working
argo.legs = {
    // totalNumber: 0, // No more needed
    [tn]: 6
};
// solution 5 = working
argo.legs = {
    totalNumber: 0,
    [BodyParts[TN]]: 6
};

Итак, если вы заранее не знаете, получите ли вы propertyA или propertyB от бэкэнда (что было моей первоначальной проблемой),и тогда вы захотите использовать вычисляемый ключ, вам, вероятно, потребуется либо установить ключ в объявлении интерфейса как необязательный, либо установить для него тип псевдонима (или перечисления), например type myType = 'propertyA' | 'propertyB', а затем использовать его какключ свойства в вашем интерфейсе, например:

interface MyInterface { 
    myType: number 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...