#typescript #type-inference
Вопрос:
В этом коде
const s = "myKey" as const;
const myF = () => ({
[s]: 0,
});
тип myF
является function myF(): {[p: string]: number, myKey: number}
где тип возвращаемого значения {[p: string]: number, myKey: number}
Как вы можете видеть, [p: string]: number
здесь нежелательные утечки.
Как сделать тип возвращаемого значения ожидаемым {MyKey: число} без явной аннотации типа?
Я пока не хочу вдаваться в явные аннотации, так как у меня есть несколько типов с большим количеством полей.
Комментарии:
1. Какую версию машинописного текста вы используете? Когда я вставляю ваш код на игровую площадку typescript , я вижу
myF
() => { myKey: number }
, что для большинства версий typescript есть тип2. Является ли ваш фактический код более сложным, чем описанный выше? Я бы предположил, что у вас может возникнуть ситуация, когда эквивалент
s
в вашем реальном коде вводится какstring
, а не как определенный тип строкового литерала и вызывает то, что вы видите.3. Игровая площадка Typescript показывает ожидаемое поведение. Возможно, проблема в том, что я проверяю инспектора типов IDEA (Ultimate / Webstorm, не имеет значения). Может быть, это действительно проблема с ИДЕЕЙ.
4. > является ли ваш фактический код более сложным, чем описанный выше? Это так, но я упростил его в этом примере.
Ответ №1:
Это поведение TypeScript по умолчанию. Он всегда оценивает вычисляемое свойство в строку.
Вы можете написать пользовательский помощник для создания объектов:
const s = "myKey";
const record = <Prop extends PropertyKey, Value>(prop: Prop, value: Value) =>
({ [prop]: value }) as Record<Prop, Value>
// const myF: () => Record<"myKey", number>
const myF = () => record(s, 42)
Вам не нужно использовать as const
Имейте в виду, что у этого решения есть недостаток.
const drawback = record<'myKey' amp; { hello?: 'world' }, 42>('myKey', 42).myKey // error
Следовательно, вам лучше избегать использования явных обобщений для этой функции
Комментарии:
1. > Это поведение TypeScript по умолчанию. Он всегда оценивает вычисляемое свойство в строку. « const prop = «PROP»; const myO = { [prop]: 1 }; « будет иметь тип
{PROP: number}
2. Я думаю, что это то, чего я пытаюсь достичь — иметь такое же поведение с возвращением функции. Мой настоящий тип немного больше, чем это — у него есть несколько реквизитов с разными типами.
3. @IgorLoskutov пожалуйста, поделитесь своим реальным примером