TypeScript: передача типизированного объекта функции, которая принимает ограниченные, но общие параметры - PullRequest
1 голос
/ 25 мая 2020

Я хочу написать функцию, которая работает только с объектами Plain Old Data (потому что я хочу использовать postMessage), а затем я хочу передать объекты этой функции:

// plain old data can only be bool, number, string
// or an array or an object composed of plain old data
type PodArray = Pod[]
type PodObject = { [index:string]:Pod }
type Pod = boolean | number | string | PodArray | PodObject

// all this works:

let test1:Pod = 1
let test2:Pod = "two"
let test3:Pod = [3, 3, 3]
let test4:Pod = {4:4}
let test5:Pod = {1:1, 2:"two", 3:[3, 3, 3], 4:{4:4}}

// this doesn't:

function send(data:Pod){
    postMessage(data, "")
}

interface MyType{
    key1:number
    key2:string
}

let data:MyType = {key1:1, key2:"2"}
send(data) // fails because Index signature is missing in type 'MyType'

TypeScript Playground

Это имеет смысл, потому что MyType не расширяет Pod и не должен, потому что мне не нужно ничего, кроме key1 и key2 в нем.

Как мне написать функция, которая принимает общие параметры определенной категории и отклоняет другие, а затем передает параметры, которые имеют гораздо более узкие типы?


Изменить: теперь у меня есть подход, который я нашел с помощью более или менее проб и ошибок:

type PodObject<T> = { [K in keyof T]:Pod<T[K]> }
type Pod<T> = T extends boolean | number | string? T:
    T extends Function? never:
    T extends Object? PodObject<T>:
    never

function send<T>(data:Pod<T>){
    postMessage(data, "")
}

interface MyType{
    key1:number
    key2:string
    key3:MyOtherType
}

interface MyOtherType{
    key4:number
    key5:number[]
}

let data:MyType = {key1:1, key2:"2", key3:{key4:3, key5:[1, 2]}}
send([{data, 5:5}])
send({})
send(function(){}) // Error
send(1)
send([1,2,3])
send({a:4, b:[1,"x",3], data, f:()=>{}}) // Error

Я разработал это, думая, что тип аргумента будет передан в условную цепочку как T. Однако, поскольку я не «вызываю» объект Pod с определенным T, но он пытается сопоставить результат условной цепочки Pod с типом аргумента (так что он действительно должен работать в обратном направлении), я действительно не понимаю, почему это работает, и я не уверен, что это на самом деле делает то, что должен делать. Любая помощь по-прежнему приветствуется.

...