TypeScript arayüzünde belirli bir dizeye nasıl ihtiyaç duyulur


144

3. taraf js kitaplığı için bir TypeScript tanım dosyası oluşturuyorum. Yöntemlerden biri, bir seçenek nesne için izin verir ve seçenekler nesnenin özelliklerinden biridir listeden bir dize kabul eder: "collapse", "expand", "end-expand", ve "none".

Seçenekler nesnesi için bir arayüzüm var:

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: // "collapse" | "expand" | "end-expand" | "none"
}

Arayüz bunu zorlayabilir mi, yani özelliğe bir IOptionsnesne eklerseniz brace_style, yalnızca kabul edilebilir listede olan bir dizeye izin verir mi?


4
Lütfen bu sorunun yanıtlarını tekrar gözden
Andreas

@Andreas'ın yorumuna göre, neden RyanQ'nun yanıtını Denis Khay'in yerine tercih ediyorsunuz ? Denis 'daha geniş anlamda uygulanabilir bir imo gibi görünüyor.
ruffin

Yanıtlar:


226

Bu sürüm 1.8'de "dize değişmez türleri" olarak yayınlandı

Typescript'teki Yenilikler - Dize Değişmez Türleri

Sayfadan örnek:

interface AnimationOptions {
  deltaX: number;
  deltaY: number;
  easing: "ease-in" | "ease-out" | "ease-in-out";
}

6
Uygulamanın içinde bu türden bir dizeyi argüman olarak iletmeniz gereken her yerde dizelerle birlikte kopyalayıp yapıştırmayı gerektirir. Her zaman tüm AnimationOptions'ı kullanıyorsanız, bu çözüm uygun görünüyor, ancak yalnızca 'yumuşatma' türünü geçebileceğiniz kullanım durumlarında bu yanlıştır. Denis Khay cevabına bakın, çok daha iyi.
Patryk Wlaź

121

Bunu dene

export type ReadingTypes = 'some'|'variants'|'of'|'strings';

export interface IReadings {
   param:ReadingTypes
}

12
Bu, oluşturulan türün uygulamanın herhangi bir yerinde yeniden kullanılmasına izin verdiği için doğru olarak işaretlenmelidir.
Patryk Wlaź

Bu tam olarak bir dizi dizeyi numaralandırılmış bir türe değer olarak geçirmenin bir yolu olarak aradığım şeydi. Enum'u tamamen atlayarak ve kullanarak type, şu örneği geçmeyi başardım: const myVar: ReadingTypes = ["some"|"variants"];dinamik bir numaralandırma yazım sözdizimini korurken. Bunun doğru olarak işaretlenmiş yanıt olması gerektiği konusunda tamamen hemfikirim.
mdawsondev

bunu kullanmanın bir yolu var mı ama böyle yumuşak bir şekilde yazılmışsa type VisibilityTypes = VISIBILITY.PUBLISH | VISBIBILITY.DRAFTbir ad alanı bulunamadı hatası alıyorum, ancak bunları zor
Max Carroll

Bir yol buldum ve yeni bir yanıt ekledim
Max Carroll

10

Belki tam olarak istediğin şey değil, ama Enumsenin için mükemmel bir çözüm gibi görünüyor.

enum BraceStyle {Collapse, Expand, EndExpand, None}

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: BraceStyle
}

Ancak numaralandırmalar sayı tabanlıdır. Bu, çalışma süresi sırasında BraceStyle.Collapsebu durumda örneğin için gerçek bir değerin 0 olacağı anlamına gelir . Ancak, nesnelere derledikleri için bunları diğer, hatta daktilo olmayan betiklerle de kullanabilirsiniz. BraceStyleDerleme ve çalıştırma işleminden sonra şu şekilde bakılacak:

{
    0: "Collapse",
    1: "Expand",
    2: "EndExpand",
    3: "None",
    Collapse: 0,
    Expand: 1,
    EndExpand: 2,
    None: 3
}

Bunun yerine dizeler istiyorsanız, burada açıklandığı gibi statik üyeli bir sınıf kullanabilirsiniz.


enums dizge değerlerine sahip olabilir (şimdi en azından 2014'te yapabileceklerinden emin değilim). enum BraceStyle { Collapse = "Collapse", Expand = "Expand" }.
ZachB

2014 yılında yapabilirlerse, cevabımda bundan bahsedirdim.
Kuba Jagoda

8

TS, Dize değişmez türleri olarak adlandırılan belirli dize değerlerine bir türleme sunar .

İşte bunların nasıl kullanılacağına dair bir örnek:

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'};

1
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

1

TypeScript 2.4'te Dize Enümlerini kullanabilirsiniz

Bu yaklaşımı tercih ediyorum çünkü aynı sabit kodlu dizginin birden fazla yerde bulunması ihtiyacını ortadan kaldırıyor.

Değerlerin dizge olduğu bir enum yapmak mümkündür

export enum VISIBILITY {
  PUBLISH = "publish",
  DRAFT = "draft"
}

Bu numaralandırma daha sonra bir arabirim veya sınıf üzerinde bir tür olarak kullanılabilir

export interface UserOptions  {
  visibility:  VISIBILITY 
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.