#typescript #types
#typescript #типы
Вопрос:
У меня есть объект как со статически известными, так и (иногда) динамическими свойствами.
Я надеюсь, что TypeScript поможет отловить опечатки. Очевидно, что это невозможно для свойств, добавленных во время выполнения, но опечатки в строковых литералах теоретически могут быть обнаружены.
Подход, который я использую, заключается в том, чтобы попытаться разрешить динамические строки, но запретить типы строковых литералов, которых нет в списке благословенных («foo» и «bar» в примере).
Например, что-то вроде этого синтаксиса может работать (но это не так):
type Options = {
foo?: boolean;
bar?: boolean;
[index: NotLiteral<string>]: boolean;
}
type NotLiteral<T> = string extends T ? never : T
const o: Options = {};
o["fooTypo"] = true; // I wish this didn't typeCheck
o[callApi()] = true; // should be OK
declare function callApi(): string;
Эти типы индексов могут быть string
или number
, вероятно, преодолимы (вероятно, есть обходной путь), но более глубокая проблема заключается в том, что string
расширяются типы строковых литералов, что на самом деле не имеет смысла.
const x: NotLiteral<"foo"> = "foo"; // type is "string", but should probably be "never"
Правила для ‘extends’, похоже, не совпадают с правилами назначения здесь (почему?):
const x: "foo" = callApi() // type error (good) even though "string" extends "foo"
Ссылка на игровую площадку: https://www.typescriptlang.org/play/index.html
Комментарии:
1. Как бы вы или TypeScript узнали, что
"fooTypo"
это опечатка"foo"
, а не правильно написанное свойство index? Также неясно, что вы имеете в видуstring extends string ? never : string
.2. если бы мы могли ввести свойство index как NotLiteral, тогда оно должно было бы иметь тип ‘string’, а не тип ‘foo’. Такого рода вещи (независимо от того, является ли строка литералом или нет), по-видимому, могут быть обнаружены для присваиваемости, но не для
extends
(см. ^)3. …что?
NotLiteral<string>
это то жеnever
самое, что и, он не собирается волшебным образом подбирать каждое значение, которое вы пытаетесь присвоить, и переоценивать тип.