Typescript enum'ini bir parametre türü olarak kullanmak geçersiz değerlere izin verir


TypeScript'te bir enum tanımlıyorum, sonra bir fonksiyonun parametresinin enum değerlerinden biri olmasını istiyorum. Ancak, TypeScript değer üzerinde herhangi bir doğrulama yapmıyor gibi görünüyor ve enum dışında değerleri de kabul ediyor. Bunu yapmanın bir yolu var mı?

Örnek

enum myenum {
    hello = 1,
    world = 2,
}

const myfunc = (num:myenum):void => console.log(`num=${num}`);

myfunc(1);            // num=1 (expected)
myfunc(myenum.hello); // num=1 (expected)

//THE ISSUE: I'm expecting next line to be a TS compile error, but it is not
myfunc(7); // num=7

Alternatif

Eğer enum yerine type kullanırsam, aradığım şeye benzer bir şey elde edebilirim, ama enum'un bazı işlevselliklerini kaybederim.

type mytype = 1|2;
const myfunc = (num:mytype):void => console.log(`num=${num}`);

myfunc(1);
myfunc(7);  //TS Compile Error: Argument of type '7' is not assignable to a parameter of type 'mytype'

Cevap #1

TS'deki enum'dan çok fazla bekliyor olabilirsiniz... :)

enum MyCoolEnum {
  A = 1,
  B = 2,
}

function test(data: MyCoolEnum) {
  console.log(`Test = ${typeof data}`)
}

test(1)
test(MyCoolEnum.A)
test(500)

Eğer yukarıdaki bu kodu çalıştırırsanız, tüm satırların number yazdırdığını göreceksiniz, bu da sahne arkasında bunun bir sayıya dönüştürüldüğü anlamına gelir ve bu yüzden her şeyi kabul eder... Enumlar genellikle sihirli sayıların kullanılmasını önlemek ve kodu daha okunabilir hale getirmek için iyi bir uygulamadır

Öte yandan, sayısal enum'ları kullanmayı bırakırsanız ve A ve B'nin değerlerini aslında string olarak değiştirirseniz, şunu alırsınız:

TSError: ⨯ Unable to compile TypeScript:
dima.ts:10:6 - error TS2345: Argument of type '1' is not assignable to parameter of type 'MyCoolEnum'.

10 test(1)
        ~
dima.ts:12:6 - error TS2345: Argument of type '500' is not assignable to parameter of type 'MyCoolEnum'.

12 test(500)
        ~~~

    at createTSError (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:423:12)
    at reportTSError (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:427:19)
    at getOutput (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:554:36)
    at Object.compile (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:760:32)
    at Module.m._compile (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:839:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:842:12)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

Yani demeye çalıştığım şey şu: Eğer sayısal bir enum ise sadece kozmetik ve bir sayı gibi muamele görüyor, ama örneğin bir string enum yaparsanız aslında türle eşleşmeye çalışıyor.

İlgili makaleler