Как потребовать определенную строку в интерфейсе TypeScript
Я создаю файл определения TypeScript для сторонней библиотеки js. Один из методов позволяет использовать объект options, а одно из свойств объекта options принимает строку из списка: "collapse"
, "expand"
, "end-expand"
и "none"
.
У меня есть интерфейс для объекта options:
interface IOptions {
indent_size?: number;
indent_char?: string;
brace_style?: // "collapse" | "expand" | "end-expand" | "none"
}
Может ли интерфейс обеспечить выполнение этого, поэтому, если вы включите объект IOptions
с свойством brace_style
, он разрешит только строку, которая находится в допустимом списке?
Ответы
Ответ 1
Это было выпущено в версии 1.8 как "строковые литералы"
Что нового в Typescript - Строковые литературные типы
Пример со страницы:
interface AnimationOptions {
deltaX: number;
deltaY: number;
easing: "ease-in" | "ease-out" | "ease-in-out";
}
Ответ 2
Попробуйте это
export type ReadingTypes = 'some'|'variants'|'of'|'strings';
export interface IReadings {
param:ReadingTypes
}
Ответ 3
Другая возможность - сделать что-то вроде:
export type BraceStyleOptions = "collapse" | "expand" | "end-expand" | "none";
export interface IOptions{
indent_size?: number;
indent_char?: string;
brace_style?: BraceStyleOptions;
}
таким образом, вы можете повторно использовать ваши параметры в любом месте, а также в других интерфейсах.
Ответ 4
Возможно, не совсем то, что вы хотели, но Enum
кажется идеальным решением для вас.
enum BraceStyle {Collapse, Expand, EndExpand, None}
interface IOptions {
indent_size?: number;
indent_char?: string;
brace_style?: BraceStyle
}
Перечисления, однако, основаны на числах. Это означает, что во время выполнения реальное значение, например, BraceStyle.Collapse
будет 0 в этом случае. Но вы можете использовать их с другими сценариями без typescript, поскольку они компилируются для объектов. Вот как BraceStyle
будет смотреть после компиляции и запуска:
{
0: "Collapse",
1: "Expand",
2: "EndExpand",
3: "None",
Collapse: 0,
Expand: 1,
EndExpand: 2,
None: 3
}
Если вы хотите использовать строки, вы можете использовать класс со статическими членами, как описано здесь
Ответ 5
TS предлагает типизацию для определенных строковых значений, которые называются строковыми литеральными типами.
Вот пример того, как их использовать:
type style = "collapse" | "expand" | "end-expand" | "none";
interface IOptions {
indent_size?: number;
indent_char?: string;
brace_style1?: "collapse" | "expand" | "end-expand" | "none";
brace_style2?: style;
}
// Ok
let obj1: IOptions = {brace_style1: 'collapse'};
// Compile time error:
// Type '"collapsessss"' is not assignable to type '"collapse" | "expand" | "end-expand" | "none" | undefined'.
let obj2: IOptions = {brace_style1: 'collapsessss'};
Ответ 6
function keysOf<T>(obj: T, key: keyof T) { return obj[key]; }
interface SomeInterface {
a: string;
}
const instance: SomeInterface = { a: 'some value'};
let value = keysOf<SomeInterface>(instance, 'b'); // invalid
value = keysOf<SomeInterface>(instance, 'a'); // valid