angular - Const Obje’den eşlemeli tipler oluştur
Aşağıdaki nesneye sahibim (bu Angular yönlendirmesini/sayfalarını tanımlar. Bazılarının değiştirilebilecek parametreleri vardır.):
const ROUTES = {
PAGE_NO_PARAMS: '/hello/page/two',
PAGE_R: '/about/:id',
PAGE_Z: '/page/page/:param/:id',
PAGE_N: '/who/:x/:y/:z/page',
} as const
Yoldaki parametreleri (:xxx) göz ardı eden bir tür geçerli sayfa türünü bu nesneden bazı türde joker karakter kullanarak oluşturabilir miyim?
Yani. Aşağıdaki gibi bir tür oluşturun (ama ROUTES nesnesini kullanarak). Benimde zaten wildcard olmadan var. Ancak, parametreli yollar çözülmüş ie. /about/xxxxx type kontrolünü karşılamıyor
type ValidRoute = '/hello/page/two' | '/about/${string}' | '/page/page/${string}/${string}'| '/who/${string}/${string}/${string}/page'
Özetle, ROUTES içindeki her özelliği dolaşmak ve /:any string/ öğesini /$ {string} ile değiştiren bir tür oluşturmak istiyorum
Umarım tüm bunlar mantıklıdır. Çalışma zamanı hatalarını derleme hatalarıyla değiştirmeye çalışıyorum.
Cevap #1
Yolu işlemek için bazı özyinelemeli koşullu tipleri kullanabilirsiniz. :name ile karşılaştığımızda bunu $string} ile değiştirebiliriz
type MakeValidRoute<T extends string, R extends string = ''> =
T extends `${infer Head}/:${infer Name}/${infer Tail}`?
MakeValidRoute<`/${Tail}`, `${R}${Head}/${string}`>:
T extends `${infer Head}/:${infer Name}`?
`${R}${Head}/${string}`:
`${R}${T}`
Oyun Alanı Bağlantısı
Bu türlerin derleyicideki performansını artırmak için kuyruk özyinelemeli koşullu türler kullanıyoruz
Cevap #2
Buradaki diğer cevap doğru. Tamamlık açısından, bunu ben şöyle yaptım:
type SubstParamNames<T extends string, S extends string = string, A extends string = ""> =
T extends `${infer F}:${infer _}/${infer R}` ? SubstParamNames<R, S, `${A}${F}${S}/`>
: T extends `${infer F}:${infer _}` ? `${A}${F}${S}` : `${A}${T}`
SubstParamNames<T, S> türü, kuyrukta özyinelemeli bir koşullu türdür ve T içindeki tüm iki nokta ile ayrılmış yol parçalarını (bir ":" ile başlar ve ya bir "/" ile biter ya da stringin sonuna kadar gider) S değerininyle değiştirir; S varsayılan olarak sadece stringtir.
Bu, aşağıdaki çıktıyı verir:
const ROUTES = {
PAGE_NO_PARAMS: '/hello/page/two',
PAGE_R: '/about/:id',
PAGE_Z: '/page/page/:param/:id',
PAGE_N: '/who/:x/:y/:z/page',
} as const
type Routes = SubstParamNames<typeof ROUTES[keyof typeof ROUTES]>
/* type RP = type Routes = "/hello/page/two" | `/about/${string}` |
`/page/page/${string}/${string}` | `/who/${string}/${string}/${string}/page`
*/
Ve eğer önemliyse, string öğesini başka bir şeyle değiştirebilirsiniz:
type IfItMatters = SubstParamNames<"/ay/:bee/cee/:dee/eee", "XXX">
// type IfItMatters = "/ay/XXX/cee/XXX/eee"
Koda yönelik oyun alanı bağlantısı
